mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 17:17:29 -05:00
Compare commits
20 Commits
v0.5.0-bet
...
v0.5.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
925353d515 | ||
|
|
7c32897321 | ||
|
|
cbeda19d27 | ||
|
|
8148ca48af | ||
|
|
adcb55ffbc | ||
|
|
1152b13220 | ||
|
|
166383e1ed | ||
|
|
0d5d1b20e3 | ||
|
|
77ea43f61a | ||
|
|
f988344222 | ||
|
|
60489e1fef | ||
|
|
ac8aa17a80 | ||
|
|
25a42126df | ||
|
|
1b90e0b50c | ||
|
|
7f5ad7eb20 | ||
|
|
0e6713b6e2 | ||
|
|
96d3996bec | ||
|
|
0fb148d31e | ||
|
|
cebca28b19 | ||
|
|
af8cc0255e |
24
build.gradle
24
build.gradle
@@ -28,7 +28,7 @@ repositories {
|
|||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
}
|
}
|
||||||
|
|
||||||
version = '0.5.0-beta2'
|
version = '0.5.0-beta3'
|
||||||
sourceCompatibility = '17'
|
sourceCompatibility = '17'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -58,7 +58,7 @@ dependencies {
|
|||||||
//mavenCentral/jcenter imports
|
//mavenCentral/jcenter imports
|
||||||
implementation 'ch.qos.logback:logback-classic:1.2.3'
|
implementation 'ch.qos.logback:logback-classic:1.2.3'
|
||||||
implementation 'ch.qos.logback:logback-core:1.2.3'
|
implementation 'ch.qos.logback:logback-core:1.2.3'
|
||||||
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.8'
|
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.13.2'
|
||||||
implementation 'com.fazecast:jSerialComm:2.5.0'
|
implementation 'com.fazecast:jSerialComm:2.5.0'
|
||||||
implementation 'com.github.jiconfont:jiconfont-font_awesome:4.7.0.1'
|
implementation 'com.github.jiconfont:jiconfont-font_awesome:4.7.0.1'
|
||||||
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
||||||
@@ -139,11 +139,11 @@ String targetWindowsX86_64 = 'windows-x86_64-v' + version
|
|||||||
* author's development environment, but can be changed to your environment if you want to use this build pattern.
|
* author's development environment, but can be changed to your environment if you want to use this build pattern.
|
||||||
*/
|
*/
|
||||||
String jdk_base = '/home/denny/java_jdks/'
|
String jdk_base = '/home/denny/java_jdks/'
|
||||||
String jdk_linux_aarch64 = jdk_base + 'linux-arm64/jdk-17.0.2-full'
|
String jdk_linux_aarch64 = jdk_base + 'linux-arm64/jdk-18.0.1-full'
|
||||||
String jdk_linux_x86_64 = jdk_base + 'linux-x64/jdk-17.0.2-full'
|
String jdk_linux_x86_64 = jdk_base + 'linux-x64/jdk-18.0.1-full'
|
||||||
String jdk_osx_x86_64 = jdk_base + 'osx-x64/jdk-17.0.2-full.jdk'
|
String jdk_osx_x86_64 = jdk_base + 'osx-x64/jdk-18.0.1-full.jdk'
|
||||||
String jdk_osx_aarch64 = jdk_base + 'osx-arm64/jdk-17.0.2-full.jdk'
|
String jdk_osx_aarch64 = jdk_base + 'osx-arm64/jdk-18.0.1-full.jdk'
|
||||||
String jdk_windows_x86_64 = jdk_base + 'windows-x64/jdk-17.0.2-full'
|
String jdk_windows_x86_64 = jdk_base + 'windows-x64/jdk-18.0.1-full'
|
||||||
|
|
||||||
boolean hasTargetJdks = file(jdk_linux_x86_64).exists() || file(jdk_linux_aarch64).exists() ||
|
boolean hasTargetJdks = file(jdk_linux_x86_64).exists() || file(jdk_linux_aarch64).exists() ||
|
||||||
file(jdk_osx_x86_64).exists() || file(jdk_osx_aarch64).exists() || file(jdk_windows_x86_64).exists()
|
file(jdk_osx_x86_64).exists() || file(jdk_osx_aarch64).exists() || file(jdk_windows_x86_64).exists()
|
||||||
@@ -172,19 +172,19 @@ runtime {
|
|||||||
println("Building all runtime images")
|
println("Building all runtime images")
|
||||||
println("The [ > jre: ] build phase downloads several target JDKs and this may take a while ... please wait")
|
println("The [ > jre: ] build phase downloads several target JDKs and this may take a while ... please wait")
|
||||||
targetPlatform(targetLinuxAarch64) {
|
targetPlatform(targetLinuxAarch64) {
|
||||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/17.0.2+9/bellsoft-jdk17.0.2+9-linux-aarch64-full.tar.gz")
|
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-linux-aarch64-full.tar.gz")
|
||||||
}
|
}
|
||||||
targetPlatform(targetLinuxX86_64) {
|
targetPlatform(targetLinuxX86_64) {
|
||||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/17.0.2+9/bellsoft-jdk17.0.2+9-linux-amd64-full.tar.gz")
|
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-linux-amd64-full.tar.gz")
|
||||||
}
|
}
|
||||||
targetPlatform(targetOsxAarch64) {
|
targetPlatform(targetOsxAarch64) {
|
||||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/17.0.2+9/bellsoft-jdk17.0.2+9-macos-aarch64-full.tar.gz")
|
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-macos-aarch64-full.tar.gz")
|
||||||
}
|
}
|
||||||
targetPlatform(targetOsxX86_64) {
|
targetPlatform(targetOsxX86_64) {
|
||||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/17.0.2+9/bellsoft-jdk17.0.2+9-macos-amd64-full.tar.gz")
|
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-macos-amd64-full.tar.gz")
|
||||||
}
|
}
|
||||||
targetPlatform(targetWindowsX86_64) {
|
targetPlatform(targetWindowsX86_64) {
|
||||||
jdkHome = jdkDownload("https://download.bell-sw.com/java/17.0.2+9/bellsoft-jdk17.0.2+9-windows-amd64-full.zip")
|
jdkHome = jdkDownload("https://download.bell-sw.com/java/18.0.1+12/bellsoft-jdk18.0.1+12-windows-amd64-full.zip")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Build using pre-downloaded JDKs
|
//Build using pre-downloaded JDKs
|
||||||
|
|||||||
21
gradle/wrapper/gradle-wrapper.properties
vendored
21
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,24 @@
|
|||||||
|
#
|
||||||
|
# ******************************************************************************
|
||||||
|
# Copyright (C) 2014-2022 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-7.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.alias;
|
package io.github.dsheirer.alias;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.alias;
|
package io.github.dsheirer.alias;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.alias;
|
package io.github.dsheirer.alias;
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class AudioSegmentBroadcaster<T extends AudioSegment> extends Broadcaster
|
|||||||
@Override
|
@Override
|
||||||
public void broadcast(T audioSegment)
|
public void broadcast(T audioSegment)
|
||||||
{
|
{
|
||||||
for(Listener<T> listener : mListeners)
|
for(Listener<T> listener : getListeners())
|
||||||
{
|
{
|
||||||
audioSegment.incrementConsumerCount();
|
audioSegment.incrementConsumerCount();
|
||||||
listener.receive(audioSegment);
|
listener.receive(audioSegment);
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.Float;
|
||||||
|
import java.lang.Math;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AudioUtils
|
public class AudioUtils
|
||||||
@@ -78,4 +81,43 @@ public class AudioUtils
|
|||||||
|
|
||||||
return stream.toByteArray();
|
return stream.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize audio samples
|
||||||
|
*/
|
||||||
|
public static List<float[]> normalize(List<float[]> audioBuffers)
|
||||||
|
{
|
||||||
|
float targetMax = 0.95f; // -0.44dBFS
|
||||||
|
float max = 0.1f; // Initialize at 0.1 (-20dBFS) to limit maximum gain
|
||||||
|
|
||||||
|
for(float[] audioBuffer: audioBuffers)
|
||||||
|
{
|
||||||
|
for(float value: audioBuffer)
|
||||||
|
{
|
||||||
|
float newMax = Math.max(max, Math.abs(value));
|
||||||
|
if(!Float.isNaN(newMax))
|
||||||
|
{
|
||||||
|
max = newMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(targetMax == max)
|
||||||
|
{
|
||||||
|
return audioBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
|
float gain = targetMax / max;
|
||||||
|
|
||||||
|
for(float[] audioBuffer: audioBuffers)
|
||||||
|
{
|
||||||
|
for(int i=0;i<audioBuffer.length;i++)
|
||||||
|
{
|
||||||
|
audioBuffer[i] *= gain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return audioBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(AudioStreamingBroadcaster.class);
|
private final static Logger mLog = LoggerFactory.getLogger(AudioStreamingBroadcaster.class);
|
||||||
|
|
||||||
public static final int PROCESSOR_RUN_INTERVAL_MS = 1000;
|
public static final int PROCESSOR_RUN_INTERVAL_MS = 1000;
|
||||||
private ScheduledFuture mRecordingQueueProcessorFuture;
|
private ScheduledFuture<?> mRecordingQueueProcessorFuture;
|
||||||
|
|
||||||
private RecordingQueueProcessor mRecordingQueueProcessor = new RecordingQueueProcessor();
|
private RecordingQueueProcessor mRecordingQueueProcessor = new RecordingQueueProcessor();
|
||||||
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
||||||
@@ -52,6 +52,10 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
private long mMaximumRecordingAge;
|
private long mMaximumRecordingAge;
|
||||||
private AtomicBoolean mStreaming = new AtomicBoolean();
|
private AtomicBoolean mStreaming = new AtomicBoolean();
|
||||||
|
|
||||||
|
protected boolean mInlineActive = false;
|
||||||
|
protected int mInlineInterval;
|
||||||
|
protected int mInlineRemaining = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AudioBroadcaster for streaming audio recordings to a remote streaming audio server. Audio recordings are
|
* AudioBroadcaster for streaming audio recordings to a remote streaming audio server. Audio recordings are
|
||||||
* generated by an internal StreamManager that converts an inbound stream of AudioPackets into a recording of the
|
* generated by an internal StreamManager that converts an inbound stream of AudioPackets into a recording of the
|
||||||
@@ -89,7 +93,7 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
/**
|
/**
|
||||||
* Broadcast binary audio data frames or sequences.
|
* Broadcast binary audio data frames or sequences.
|
||||||
*/
|
*/
|
||||||
protected abstract void broadcastAudio(byte[] audio);
|
protected abstract void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol-specific metadata updater
|
* Protocol-specific metadata updater
|
||||||
@@ -205,13 +209,15 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
|
|
||||||
super.setBroadcastState(state);
|
super.setBroadcastState(state);
|
||||||
|
|
||||||
if(mBroadcastState.get() instanceof BroadcastState && ((BroadcastState)mBroadcastState.get()).isErrorState())
|
if(mBroadcastState.get() != null && mBroadcastState.get().isErrorState())
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!connected())
|
if(!connected())
|
||||||
{
|
{
|
||||||
|
//Reset inline metadata
|
||||||
|
mInlineRemaining = -1;
|
||||||
//Remove all pending audio recordings
|
//Remove all pending audio recordings
|
||||||
while(!mAudioRecordingQueue.isEmpty())
|
while(!mAudioRecordingQueue.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -265,9 +271,9 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
{
|
{
|
||||||
private AtomicBoolean mProcessing = new AtomicBoolean();
|
private AtomicBoolean mProcessing = new AtomicBoolean();
|
||||||
private ByteArrayInputStream mInputStream;
|
private ByteArrayInputStream mInputStream;
|
||||||
|
private IdentifierCollection mInputIdentifierCollection;
|
||||||
private long mFinalSilencePadding = 0;
|
private long mFinalSilencePadding = 0;
|
||||||
private int mBytesStreamedActual = 0;
|
private int mBytesToStreamPerInterval = 0;
|
||||||
private int mBytesStreamedRequired = 0;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
@@ -278,51 +284,44 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
{
|
{
|
||||||
if(mInputStream == null || mInputStream.available() <= 0)
|
if(mInputStream == null || mInputStream.available() <= 0)
|
||||||
{
|
{
|
||||||
if(mFinalSilencePadding > 0)
|
|
||||||
{
|
|
||||||
List<byte[]> finalSilence = mSilenceGenerator.generate(mFinalSilencePadding);
|
|
||||||
|
|
||||||
for(byte[] silence: finalSilence)
|
|
||||||
{
|
|
||||||
broadcastAudio(silence);
|
|
||||||
}
|
|
||||||
|
|
||||||
mFinalSilencePadding = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextRecording();
|
nextRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mInputStream != null)
|
if(mInputStream != null)
|
||||||
{
|
{
|
||||||
//We need to stream at 13.888 fps (144 byte frame) to achieve 2000 Bps or 16 kbps
|
int length = FastMath.min(mBytesToStreamPerInterval, mInputStream.available());
|
||||||
mBytesStreamedRequired += 2000; //2000 bytes per second for 16 kbps data rate
|
|
||||||
int bytesToStream = mBytesStreamedRequired - mBytesStreamedActual;
|
|
||||||
|
|
||||||
//Trim length to whole-frame intervals (144 byte frame)
|
|
||||||
bytesToStream -= (bytesToStream % 144);
|
|
||||||
|
|
||||||
int length = FastMath.min(bytesToStream, mInputStream.available());
|
|
||||||
|
|
||||||
byte[] audio = new byte[length];
|
byte[] audio = new byte[length];
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mBytesStreamedActual += mInputStream.read(audio);
|
int read = mInputStream.read(audio);
|
||||||
|
broadcastAudio(audio, mInputIdentifierCollection);
|
||||||
broadcastAudio(audio);
|
|
||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(IOException ioe)
|
||||||
{
|
{
|
||||||
mLog.error("Error reading from in-memory audio recording input stream", ioe);
|
mLog.error("Error reading from in-memory audio recording input stream", ioe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If this is the final frame fragment then append silence padding to fill the final interval segment
|
||||||
|
if(length < mBytesToStreamPerInterval && mFinalSilencePadding > 0)
|
||||||
|
{
|
||||||
|
List<byte[]> finalSilence = mSilenceGenerator.generate(mFinalSilencePadding);
|
||||||
|
|
||||||
|
for(byte[] silence: finalSilence)
|
||||||
|
{
|
||||||
|
broadcastAudio(silence, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFinalSilencePadding = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
List<byte[]> silenceFrames = mSilenceGenerator.generate(PROCESSOR_RUN_INTERVAL_MS);
|
List<byte[]> silenceFrames = mSilenceGenerator.generate(PROCESSOR_RUN_INTERVAL_MS);
|
||||||
for(byte[] silence: silenceFrames)
|
for(byte[] silence: silenceFrames)
|
||||||
{
|
{
|
||||||
broadcastAudio(silence);
|
broadcastAudio(silence, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,9 +339,6 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
*/
|
*/
|
||||||
private void nextRecording()
|
private void nextRecording()
|
||||||
{
|
{
|
||||||
mBytesStreamedActual = 0;
|
|
||||||
mBytesStreamedRequired = 0;
|
|
||||||
|
|
||||||
boolean metadataUpdateRequired = false;
|
boolean metadataUpdateRequired = false;
|
||||||
|
|
||||||
if(mInputStream != null)
|
if(mInputStream != null)
|
||||||
@@ -354,6 +350,7 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
}
|
}
|
||||||
|
|
||||||
mInputStream = null;
|
mInputStream = null;
|
||||||
|
mInputIdentifierCollection = null;
|
||||||
|
|
||||||
//Peek at the next recording but don't remove it from the queue yet, so we can inspect the start time for
|
//Peek at the next recording but don't remove it from the queue yet, so we can inspect the start time for
|
||||||
//age limits and/or delay elapsed
|
//age limits and/or delay elapsed
|
||||||
@@ -381,9 +378,14 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
{
|
{
|
||||||
byte[] audio = Files.readAllBytes(nextRecording.getPath());
|
byte[] audio = Files.readAllBytes(nextRecording.getPath());
|
||||||
|
|
||||||
if(audio != null && audio.length > 0)
|
if(audio.length > 0)
|
||||||
{
|
{
|
||||||
|
//Calculate how many bytes we'll send with each processor run interval
|
||||||
|
double intervals = (double)nextRecording.getRecordingLength() / (double)PROCESSOR_RUN_INTERVAL_MS;
|
||||||
|
mBytesToStreamPerInterval = (int)((double)audio.length / intervals);
|
||||||
|
|
||||||
mInputStream = new ByteArrayInputStream(audio);
|
mInputStream = new ByteArrayInputStream(audio);
|
||||||
|
mInputIdentifierCollection = nextRecording.getIdentifierCollection();
|
||||||
|
|
||||||
mFinalSilencePadding = PROCESSOR_RUN_INTERVAL_MS -
|
mFinalSilencePadding = PROCESSOR_RUN_INTERVAL_MS -
|
||||||
(nextRecording.getRecordingLength() % PROCESSOR_RUN_INTERVAL_MS);
|
(nextRecording.getRecordingLength() % PROCESSOR_RUN_INTERVAL_MS);
|
||||||
@@ -408,6 +410,7 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
|||||||
"stream recording [" + nextRecording.getPath().toString() + "] - skipping recording - ", ioe);
|
"stream recording [" + nextRecording.getPath().toString() + "] - skipping recording - ", ioe);
|
||||||
|
|
||||||
mInputStream = null;
|
mInputStream = null;
|
||||||
|
mInputIdentifierCollection = null;
|
||||||
metadataUpdateRequired = false;
|
metadataUpdateRequired = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
|||||||
private static final String MULTIPART_TYPE = "multipart";
|
private static final String MULTIPART_TYPE = "multipart";
|
||||||
private static final String DEFAULT_SUBTYPE = "form-data";
|
private static final String DEFAULT_SUBTYPE = "form-data";
|
||||||
private static final String MULTIPART_FORM_DATA = MULTIPART_TYPE + "/" + DEFAULT_SUBTYPE;
|
private static final String MULTIPART_FORM_DATA = MULTIPART_TYPE + "/" + DEFAULT_SUBTYPE;
|
||||||
|
private ScheduledFuture<?> mBroadcastifyTestFuture;
|
||||||
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
||||||
private ScheduledFuture<?> mAudioRecordingProcessorFuture;
|
private ScheduledFuture<?> mAudioRecordingProcessorFuture;
|
||||||
private HttpClient mHttpClient = HttpClient.newBuilder()
|
private HttpClient mHttpClient = HttpClient.newBuilder()
|
||||||
@@ -109,6 +110,12 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
|||||||
setBroadcastState(BroadcastState.ERROR);
|
setBroadcastState(BroadcastState.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(mBroadcastifyTestFuture == null && getBroadcastConfiguration().isTestEnabled())
|
||||||
|
{
|
||||||
|
// Test periodically so we don't get marked offline due to radio inactivity
|
||||||
|
mBroadcastifyTestFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new BroadcastifyCallTest(), getBroadcastConfiguration().getTestInterval(), getBroadcastConfiguration().getTestInterval(), TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
if(mAudioRecordingProcessorFuture == null)
|
if(mAudioRecordingProcessorFuture == null)
|
||||||
{
|
{
|
||||||
mAudioRecordingProcessorFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new AudioRecordingProcessor(),
|
mAudioRecordingProcessorFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new AudioRecordingProcessor(),
|
||||||
@@ -122,6 +129,11 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
|||||||
@Override
|
@Override
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
if(mBroadcastifyTestFuture != null)
|
||||||
|
{
|
||||||
|
mBroadcastifyTestFuture.cancel(true);
|
||||||
|
mBroadcastifyTestFuture = null;
|
||||||
|
}
|
||||||
if(mAudioRecordingProcessorFuture != null)
|
if(mAudioRecordingProcessorFuture != null)
|
||||||
{
|
{
|
||||||
mAudioRecordingProcessorFuture.cancel(true);
|
mAudioRecordingProcessorFuture.cancel(true);
|
||||||
@@ -131,6 +143,23 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BroadcastifyCallTest implements Runnable
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
String response = testConnection(getBroadcastConfiguration());
|
||||||
|
if(response != null && response.toLowerCase().startsWith("ok"))
|
||||||
|
{
|
||||||
|
mLog.info("Broadcastify Calls keep-alive success");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.info("Broadcastify Calls keep-alive failure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares for disposal
|
* Prepares for disposal
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,7 +24,9 @@ import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
|
|||||||
import io.github.dsheirer.audio.broadcast.BroadcastFormat;
|
import io.github.dsheirer.audio.broadcast.BroadcastFormat;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastServerType;
|
import io.github.dsheirer.audio.broadcast.BroadcastServerType;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleIntegerProperty;
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
@@ -42,6 +44,8 @@ public class BroadcastifyCallConfiguration extends BroadcastConfiguration
|
|||||||
|
|
||||||
private IntegerProperty mSystemID = new SimpleIntegerProperty();
|
private IntegerProperty mSystemID = new SimpleIntegerProperty();
|
||||||
private StringProperty mApiKey = new SimpleStringProperty();
|
private StringProperty mApiKey = new SimpleStringProperty();
|
||||||
|
private BooleanProperty mTestEnabled= new SimpleBooleanProperty(false);
|
||||||
|
private IntegerProperty mTestInterval = new SimpleIntegerProperty(15);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for faster jackson
|
* Constructor for faster jackson
|
||||||
@@ -128,6 +132,34 @@ public class BroadcastifyCallConfiguration extends BroadcastConfiguration
|
|||||||
return BroadcastServerType.BROADCASTIFY_CALL;
|
return BroadcastServerType.BROADCASTIFY_CALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this instance should schedule tests after connecting
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(isAttribute = true, localName = "test_enabled")
|
||||||
|
public boolean isTestEnabled()
|
||||||
|
{
|
||||||
|
return mTestEnabled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTestEnabled(boolean enabled)
|
||||||
|
{
|
||||||
|
mTestEnabled.set(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the interval at which tests should be performed while enabled
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(isAttribute = true, localName = "test_interval")
|
||||||
|
public int getTestInterval()
|
||||||
|
{
|
||||||
|
return mTestInterval.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTestInterval(int interval)
|
||||||
|
{
|
||||||
|
mTestInterval.set(interval);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BroadcastConfiguration copyOf()
|
public BroadcastConfiguration copyOf()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class BroadcastifyFeedConfiguration extends IcecastTCPConfiguration
|
|||||||
setBitRate(16);
|
setBitRate(16);
|
||||||
setChannels(1);
|
setChannels(1);
|
||||||
setSampleRate(8000);
|
setSampleRate(8000);
|
||||||
|
setInline(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BroadcastifyFeedConfiguration from(UserFeedBroadcast userFeedBroadcast)
|
public static BroadcastifyFeedConfiguration from(UserFeedBroadcast userFeedBroadcast)
|
||||||
@@ -86,9 +87,9 @@ public class BroadcastifyFeedConfiguration extends IcecastTCPConfiguration
|
|||||||
copy.setName(getName());
|
copy.setName(getName());
|
||||||
copy.setHost(getHost());
|
copy.setHost(getHost());
|
||||||
copy.setPort(getPort());
|
copy.setPort(getPort());
|
||||||
|
copy.setInline(getInline());
|
||||||
copy.setPassword(getPassword());
|
copy.setPassword(getPassword());
|
||||||
copy.setDelay(getDelay());
|
copy.setDelay(getDelay());
|
||||||
|
|
||||||
copy.setEnabled(false);
|
copy.setEnabled(false);
|
||||||
|
|
||||||
//Icecast Configuration Parameters
|
//Icecast Configuration Parameters
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import io.github.dsheirer.audio.convert.MP3Setting;
|
|||||||
public abstract class IcecastAudioBroadcaster extends AudioStreamingBroadcaster
|
public abstract class IcecastAudioBroadcaster extends AudioStreamingBroadcaster
|
||||||
{
|
{
|
||||||
private IBroadcastMetadataUpdater mMetadataUpdater;
|
private IBroadcastMetadataUpdater mMetadataUpdater;
|
||||||
private AliasModel mAliasModel;
|
protected AliasModel mAliasModel;
|
||||||
|
|
||||||
public IcecastAudioBroadcaster(BroadcastConfiguration broadcastConfiguration, InputAudioFormat inputAudioFormat,
|
public IcecastAudioBroadcaster(BroadcastConfiguration broadcastConfiguration, InputAudioFormat inputAudioFormat,
|
||||||
MP3Setting mp3Setting, AliasModel aliasModel)
|
MP3Setting mp3Setting, AliasModel aliasModel)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import io.github.dsheirer.alias.Alias;
|
|||||||
import io.github.dsheirer.alias.AliasList;
|
import io.github.dsheirer.alias.AliasList;
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.audio.broadcast.IBroadcastMetadataUpdater;
|
import io.github.dsheirer.audio.broadcast.IBroadcastMetadataUpdater;
|
||||||
|
import io.github.dsheirer.audio.broadcast.icecast.IcecastConfiguration;
|
||||||
|
import io.github.dsheirer.audio.broadcast.icecast.IcecastMetadata;
|
||||||
import io.github.dsheirer.identifier.Form;
|
import io.github.dsheirer.identifier.Form;
|
||||||
import io.github.dsheirer.identifier.Identifier;
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
import io.github.dsheirer.identifier.IdentifierClass;
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
@@ -73,6 +75,12 @@ public class IcecastBroadcastMetadataUpdater implements IBroadcastMetadataUpdate
|
|||||||
*/
|
*/
|
||||||
public void update(IdentifierCollection identifierCollection)
|
public void update(IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
|
if(mIcecastConfiguration.hasInline())
|
||||||
|
{
|
||||||
|
// Never send out-of-band metadata if inline metadata is enabled.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -84,7 +92,7 @@ public class IcecastBroadcastMetadataUpdater implements IBroadcastMetadataUpdate
|
|||||||
sb.append("/admin/metadata?mode=updinfo&mount=");
|
sb.append("/admin/metadata?mode=updinfo&mount=");
|
||||||
sb.append(URLEncoder.encode(mIcecastConfiguration.getMountPoint(), UTF8));
|
sb.append(URLEncoder.encode(mIcecastConfiguration.getMountPoint(), UTF8));
|
||||||
sb.append("&charset=UTF%2d8");
|
sb.append("&charset=UTF%2d8");
|
||||||
sb.append("&song=").append(URLEncoder.encode(getSong(identifierCollection), UTF8));
|
sb.append("&song=").append(URLEncoder.encode(IcecastMetadata.getTitle(identifierCollection, mAliasModel), UTF8));
|
||||||
}
|
}
|
||||||
catch(UnsupportedEncodingException uee)
|
catch(UnsupportedEncodingException uee)
|
||||||
{
|
{
|
||||||
@@ -157,82 +165,4 @@ public class IcecastBroadcastMetadataUpdater implements IBroadcastMetadataUpdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the song information for a metadata update
|
|
||||||
*/
|
|
||||||
private String getSong(IdentifierCollection identifierCollection)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
|
|
||||||
if(identifierCollection != null)
|
|
||||||
{
|
|
||||||
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
|
||||||
|
|
||||||
Identifier to = identifierCollection.getIdentifier(IdentifierClass.USER, Form.PATCH_GROUP, Role.TO);
|
|
||||||
|
|
||||||
if(to == null)
|
|
||||||
{
|
|
||||||
to = identifierCollection.getIdentifier(IdentifierClass.USER, Form.TALKGROUP, Role.TO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(to == null)
|
|
||||||
{
|
|
||||||
List<Identifier> toIdentifiers = identifierCollection.getIdentifiers(Role.TO);
|
|
||||||
if(!toIdentifiers.isEmpty())
|
|
||||||
{
|
|
||||||
to = toIdentifiers.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(to != null)
|
|
||||||
{
|
|
||||||
sb.append("TO:").append(to);
|
|
||||||
|
|
||||||
List<Alias> aliases = aliasList.getAliases(to);
|
|
||||||
|
|
||||||
if(aliases != null && !aliases.isEmpty())
|
|
||||||
{
|
|
||||||
sb.append(" ").append(Joiner.on(", ").skipNulls().join(aliases));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.append("TO:UNKNOWN");
|
|
||||||
}
|
|
||||||
|
|
||||||
Identifier from = identifierCollection.getIdentifier(IdentifierClass.USER, Form.RADIO, Role.FROM);
|
|
||||||
|
|
||||||
if(from == null)
|
|
||||||
{
|
|
||||||
List<Identifier> fromIdentifiers = identifierCollection.getIdentifiers(Role.FROM);
|
|
||||||
|
|
||||||
if(!fromIdentifiers.isEmpty())
|
|
||||||
{
|
|
||||||
from = fromIdentifiers.get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(from != null)
|
|
||||||
{
|
|
||||||
sb.append(" FROM:").append(from);
|
|
||||||
|
|
||||||
List<Alias> aliases = aliasList.getAliases(from);
|
|
||||||
|
|
||||||
if(aliases != null && !aliases.isEmpty())
|
|
||||||
{
|
|
||||||
sb.append(" ").append(Joiner.on(", ").skipNulls().join(aliases));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.append(" FROM:UNKNOWN");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.append("Scanning ....");
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ public abstract class IcecastConfiguration extends BroadcastConfiguration
|
|||||||
private int mChannels = 1;
|
private int mChannels = 1;
|
||||||
private int mSampleRate = 8000;
|
private int mSampleRate = 8000;
|
||||||
private String mURL;
|
private String mURL;
|
||||||
|
private boolean mInline = true;
|
||||||
|
|
||||||
public IcecastConfiguration(BroadcastFormat format)
|
public IcecastConfiguration(BroadcastFormat format)
|
||||||
{
|
{
|
||||||
@@ -275,6 +276,37 @@ public abstract class IcecastConfiguration extends BroadcastConfiguration
|
|||||||
return mURL != null;
|
return mURL != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control whether metadata is sent inline or out-of-band.
|
||||||
|
*/
|
||||||
|
@JacksonXmlProperty(isAttribute = true, localName = "inline")
|
||||||
|
public boolean getInline()
|
||||||
|
{
|
||||||
|
return mInline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public int getInlineInterval()
|
||||||
|
{
|
||||||
|
if (hasBitRate())
|
||||||
|
{
|
||||||
|
// Interval = BitRate * 1000 / 8 = 1 second
|
||||||
|
return getBitRate() * 125;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInline(boolean inline)
|
||||||
|
{
|
||||||
|
mInline = inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasInline()
|
||||||
|
{
|
||||||
|
// Bitrate must be known to calculate metadata interval
|
||||||
|
return mInline != false && hasBitRate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid()
|
public boolean isValid()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,9 +20,11 @@ package io.github.dsheirer.audio.broadcast.icecast;
|
|||||||
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastState;
|
import io.github.dsheirer.audio.broadcast.BroadcastState;
|
||||||
|
import io.github.dsheirer.audio.broadcast.icecast.IcecastMetadata;
|
||||||
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
||||||
import io.github.dsheirer.audio.convert.MP3AudioConverter;
|
import io.github.dsheirer.audio.convert.MP3AudioConverter;
|
||||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||||
import io.github.dsheirer.properties.SystemProperties;
|
import io.github.dsheirer.properties.SystemProperties;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import org.apache.mina.core.RuntimeIoException;
|
import org.apache.mina.core.RuntimeIoException;
|
||||||
@@ -42,6 +44,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
@@ -80,14 +83,41 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
* Broadcasts the audio frame or sequence
|
* Broadcasts the audio frame or sequence
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void broadcastAudio(byte[] audio)
|
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
||||||
{
|
{
|
||||||
IoBuffer buffer = IoBuffer.allocate(audio.length);
|
IoBuffer buffer = IoBuffer.allocate(audio.length);
|
||||||
buffer.put(audio);
|
|
||||||
buffer.flip();
|
|
||||||
|
|
||||||
|
if(mInlineActive)
|
||||||
|
{
|
||||||
|
byte[] metadata = IcecastMetadata.formatInline(IcecastMetadata.getTitle(identifierCollection, mAliasModel)).getBytes();
|
||||||
|
buffer.setAutoExpand(true);
|
||||||
|
if (mInlineRemaining == -1)
|
||||||
|
{
|
||||||
|
mInlineRemaining = mInlineInterval;
|
||||||
|
}
|
||||||
|
int audioOffset = 0;
|
||||||
|
while(audioOffset < audio.length)
|
||||||
|
{
|
||||||
|
byte[] chunk = Arrays.copyOfRange(audio, audioOffset, Math.min(audioOffset + mInlineRemaining, audio.length));
|
||||||
|
mInlineRemaining -= chunk.length;
|
||||||
|
audioOffset += chunk.length;
|
||||||
|
buffer.put(chunk);
|
||||||
|
if(mInlineRemaining == 0)
|
||||||
|
{
|
||||||
|
mInlineRemaining = mInlineInterval;
|
||||||
|
buffer.put(metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.shrink();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.put(audio);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.flip();
|
||||||
mStreamingSession.write(buffer);
|
mStreamingSession.write(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,6 +268,17 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
{
|
{
|
||||||
mHTTPHeaders.put(IcecastHeader.BITRATE.getValue(), String.valueOf(getConfiguration().getBitRate()));
|
mHTTPHeaders.put(IcecastHeader.BITRATE.getValue(), String.valueOf(getConfiguration().getBitRate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(getConfiguration().hasInline())
|
||||||
|
{
|
||||||
|
mInlineActive = true;
|
||||||
|
mInlineInterval = getConfiguration().getInlineInterval();
|
||||||
|
mHTTPHeaders.put(IcecastHeader.METAINT.getValue(), String.valueOf(mInlineInterval));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInlineActive = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mHTTPHeaders;
|
return mHTTPHeaders;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public class IcecastHTTPConfiguration extends IcecastConfiguration
|
|||||||
copy.setName(getName());
|
copy.setName(getName());
|
||||||
copy.setHost(getHost());
|
copy.setHost(getHost());
|
||||||
copy.setPort(getPort());
|
copy.setPort(getPort());
|
||||||
|
copy.setInline(getInline());
|
||||||
copy.setPassword(getPassword());
|
copy.setPassword(getPassword());
|
||||||
copy.setDelay(getDelay());
|
copy.setDelay(getDelay());
|
||||||
copy.setEnabled(false);
|
copy.setEnabled(false);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public enum IcecastHeader
|
|||||||
PUBLIC("ice-public"),
|
PUBLIC("ice-public"),
|
||||||
URL("ice-url"),
|
URL("ice-url"),
|
||||||
USER_AGENT("User-Agent"),
|
USER_AGENT("User-Agent"),
|
||||||
|
METAINT("icy-metaint"),
|
||||||
|
|
||||||
UNKNOWN("unknown");
|
UNKNOWN("unknown");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * ******************************************************************************
|
||||||
|
* * 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/>
|
||||||
|
* * *****************************************************************************
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package io.github.dsheirer.audio.broadcast.icecast;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import io.github.dsheirer.alias.Alias;
|
||||||
|
import io.github.dsheirer.alias.AliasList;
|
||||||
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
|
import io.github.dsheirer.audio.broadcast.icecast.IcecastConfiguration;
|
||||||
|
import io.github.dsheirer.identifier.Form;
|
||||||
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||||
|
import io.github.dsheirer.identifier.Role;
|
||||||
|
import io.github.dsheirer.properties.SystemProperties;
|
||||||
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IcecastMetadata
|
||||||
|
{
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(IcecastMetadata.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the title for a metadata update
|
||||||
|
*/
|
||||||
|
public static String getTitle(IdentifierCollection identifierCollection, AliasModel AliasModel)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
if(identifierCollection != null)
|
||||||
|
{
|
||||||
|
AliasList aliasList = AliasModel.getAliasList(identifierCollection);
|
||||||
|
|
||||||
|
Identifier to = identifierCollection.getIdentifier(IdentifierClass.USER, Form.PATCH_GROUP, Role.TO);
|
||||||
|
|
||||||
|
if(to == null)
|
||||||
|
{
|
||||||
|
to = identifierCollection.getIdentifier(IdentifierClass.USER, Form.TALKGROUP, Role.TO);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(to == null)
|
||||||
|
{
|
||||||
|
List<Identifier> toIdentifiers = identifierCollection.getIdentifiers(Role.TO);
|
||||||
|
if(!toIdentifiers.isEmpty())
|
||||||
|
{
|
||||||
|
to = toIdentifiers.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(to != null)
|
||||||
|
{
|
||||||
|
sb.append("TO:").append(to);
|
||||||
|
|
||||||
|
List<Alias> aliases = aliasList.getAliases(to);
|
||||||
|
|
||||||
|
if(aliases != null && !aliases.isEmpty())
|
||||||
|
{
|
||||||
|
sb.append(" ").append(Joiner.on(", ").skipNulls().join(aliases));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append("TO:UNKNOWN");
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier from = identifierCollection.getIdentifier(IdentifierClass.USER, Form.RADIO, Role.FROM);
|
||||||
|
|
||||||
|
if(from == null)
|
||||||
|
{
|
||||||
|
List<Identifier> fromIdentifiers = identifierCollection.getIdentifiers(Role.FROM);
|
||||||
|
|
||||||
|
if(!fromIdentifiers.isEmpty())
|
||||||
|
{
|
||||||
|
from = fromIdentifiers.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(from != null)
|
||||||
|
{
|
||||||
|
sb.append(" FROM:").append(from);
|
||||||
|
|
||||||
|
List<Alias> aliases = aliasList.getAliases(from);
|
||||||
|
|
||||||
|
if(aliases != null && !aliases.isEmpty())
|
||||||
|
{
|
||||||
|
sb.append(" ").append(Joiner.on(", ").skipNulls().join(aliases));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append(" FROM:UNKNOWN");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.append("Scanning...");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String formatInline(String title)
|
||||||
|
{
|
||||||
|
title = "StreamTitle='" + title + "';";
|
||||||
|
int chunks = (int)Math.ceil((title.length() + 1) / 16.0d);
|
||||||
|
int nulls = (chunks * 16) - title.length();
|
||||||
|
char[] padding = new char[nulls];
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append((char)chunks).append(title).append(padding);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,9 +21,11 @@ package io.github.dsheirer.audio.broadcast.icecast;
|
|||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastState;
|
import io.github.dsheirer.audio.broadcast.BroadcastState;
|
||||||
import io.github.dsheirer.audio.broadcast.icecast.codec.IcecastCodecFactory;
|
import io.github.dsheirer.audio.broadcast.icecast.codec.IcecastCodecFactory;
|
||||||
|
import io.github.dsheirer.audio.broadcast.icecast.IcecastMetadata;
|
||||||
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
||||||
import io.github.dsheirer.audio.convert.MP3AudioConverter;
|
import io.github.dsheirer.audio.convert.MP3AudioConverter;
|
||||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||||
import io.github.dsheirer.properties.SystemProperties;
|
import io.github.dsheirer.properties.SystemProperties;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import org.apache.mina.core.RuntimeIoException;
|
import org.apache.mina.core.RuntimeIoException;
|
||||||
@@ -39,13 +41,14 @@ import java.io.IOException;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.nio.channels.UnresolvedAddressException;
|
import java.nio.channels.UnresolvedAddressException;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
|
public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(IcecastTCPAudioBroadcaster.class);
|
private final static Logger mLog = LoggerFactory.getLogger(IcecastTCPAudioBroadcaster.class);
|
||||||
private final static String TERMINATOR = "\r\n";
|
private final static String TERMINATOR = "\n";
|
||||||
private final static String SEPARATOR = ":";
|
private final static String SEPARATOR = ":";
|
||||||
private static final long RECONNECT_INTERVAL_MILLISECONDS = 3000; //3 seconds
|
private static final long RECONNECT_INTERVAL_MILLISECONDS = 3000; //3 seconds
|
||||||
private static final long CONNECTION_ATTEMPT_TIMEOUT_MILLISECONDS = 5000; //5 seconds
|
private static final long CONNECTION_ATTEMPT_TIMEOUT_MILLISECONDS = 5000; //5 seconds
|
||||||
@@ -78,11 +81,35 @@ public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
* Broadcasts the audio frame or sequence
|
* Broadcasts the audio frame or sequence
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void broadcastAudio(byte[] audio)
|
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
||||||
{
|
{
|
||||||
mStreamingSession.write(audio);
|
if(mInlineActive)
|
||||||
|
{
|
||||||
|
byte[] metadata = IcecastMetadata.formatInline(IcecastMetadata.getTitle(identifierCollection, mAliasModel)).getBytes();
|
||||||
|
if (mInlineRemaining == -1)
|
||||||
|
{
|
||||||
|
mInlineRemaining = mInlineInterval;
|
||||||
|
}
|
||||||
|
int audioOffset = 0;
|
||||||
|
while(audioOffset < audio.length)
|
||||||
|
{
|
||||||
|
byte[] chunk = Arrays.copyOfRange(audio, audioOffset, Math.min(audioOffset + mInlineRemaining, audio.length));
|
||||||
|
mInlineRemaining -= chunk.length;
|
||||||
|
audioOffset += chunk.length;
|
||||||
|
mStreamingSession.write(chunk);
|
||||||
|
if(mInlineRemaining == 0)
|
||||||
|
{
|
||||||
|
mInlineRemaining = mInlineInterval;
|
||||||
|
mStreamingSession.write(metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mStreamingSession.write(audio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +265,18 @@ public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
.append(getConfiguration().getDescription()).append(TERMINATOR);
|
.append(getConfiguration().getDescription()).append(TERMINATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(TERMINATOR).append(TERMINATOR);
|
if(getConfiguration().hasInline())
|
||||||
|
{
|
||||||
|
mInlineActive = true;
|
||||||
|
mInlineInterval = getConfiguration().getInlineInterval();
|
||||||
|
sb.append(IcecastHeader.METAINT.getValue()).append(SEPARATOR)
|
||||||
|
.append(String.valueOf(mInlineInterval))
|
||||||
|
.append(TERMINATOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mInlineActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
session.write(sb.toString());
|
session.write(sb.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class IcecastTCPConfiguration extends IcecastConfiguration
|
|||||||
copy.setName(getName());
|
copy.setName(getName());
|
||||||
copy.setHost(getHost());
|
copy.setHost(getHost());
|
||||||
copy.setPort(getPort());
|
copy.setPort(getPort());
|
||||||
|
copy.setInline(getInline());
|
||||||
copy.setPassword(getPassword());
|
copy.setPassword(getPassword());
|
||||||
copy.setDelay(getDelay());
|
copy.setDelay(getDelay());
|
||||||
copy.setEnabled(false);
|
copy.setEnabled(false);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast.icecast.codec;
|
package io.github.dsheirer.audio.broadcast.icecast.codec;
|
||||||
|
|
||||||
import org.apache.mina.core.buffer.IoBuffer;
|
import org.apache.mina.core.buffer.IoBuffer;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.github.dsheirer.audio.broadcast.BroadcastState;
|
|||||||
import io.github.dsheirer.audio.broadcast.IBroadcastMetadataUpdater;
|
import io.github.dsheirer.audio.broadcast.IBroadcastMetadataUpdater;
|
||||||
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
||||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import org.apache.mina.core.RuntimeIoException;
|
import org.apache.mina.core.RuntimeIoException;
|
||||||
import org.apache.mina.core.buffer.IoBuffer;
|
import org.apache.mina.core.buffer.IoBuffer;
|
||||||
@@ -93,7 +94,7 @@ public class ShoutcastV1AudioBroadcaster extends AudioStreamingBroadcaster
|
|||||||
* Broadcasts the audio frame or sequence
|
* Broadcasts the audio frame or sequence
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void broadcastAudio(byte[] audio)
|
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class ShoutcastV2AudioStreamingBroadcaster extends AudioStreamingBroadcas
|
|||||||
* Broadcasts the audio frame or sequence
|
* Broadcasts the audio frame or sequence
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void broadcastAudio(byte[] audio)
|
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
//Dispatch any queued metadata messages
|
//Dispatch any queued metadata messages
|
||||||
UltravoxMessage metadataMessage = mMetadataMessageQueue.poll();
|
UltravoxMessage metadataMessage = mMetadataMessageQueue.poll();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||||
|
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastFormat;
|
import io.github.dsheirer.audio.broadcast.BroadcastFormat;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||||
|
|
||||||
import io.github.dsheirer.bits.BinaryMessage;
|
import io.github.dsheirer.bits.BinaryMessage;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||||
|
|
||||||
public class UltravoxMessageFactory
|
public class UltravoxMessageFactory
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2021 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package io.github.dsheirer.audio.convert;
|
package io.github.dsheirer.audio.convert;
|
||||||
|
|
||||||
|
import io.github.dsheirer.audio.AudioUtils;
|
||||||
import io.github.dsheirer.dsp.filter.resample.RealResampler;
|
import io.github.dsheirer.dsp.filter.resample.RealResampler;
|
||||||
import io.github.dsheirer.sample.ConversionUtils;
|
import io.github.dsheirer.sample.ConversionUtils;
|
||||||
import net.sourceforge.lame.lowlevel.LameEncoder;
|
import net.sourceforge.lame.lowlevel.LameEncoder;
|
||||||
@@ -73,6 +74,7 @@ public class MP3AudioConverter implements IAudioConverter
|
|||||||
public List<byte[]> convert(List<float[]> audioPackets)
|
public List<byte[]> convert(List<float[]> audioPackets)
|
||||||
{
|
{
|
||||||
List<byte[]> converted = new ArrayList<>();
|
List<byte[]> converted = new ArrayList<>();
|
||||||
|
audioPackets = AudioUtils.normalize(audioPackets);
|
||||||
|
|
||||||
if(mResampler != null)
|
if(mResampler != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ public enum MP3Setting
|
|||||||
CBR_16(false, 16, "CBR - Constant Bit Rate 16 kbps (default)"),
|
CBR_16(false, 16, "CBR - Constant Bit Rate 16 kbps (default)"),
|
||||||
CBR_32(false, 32, "CBR - Constant Bit Rate 32 kbps"),
|
CBR_32(false, 32, "CBR - Constant Bit Rate 32 kbps"),
|
||||||
ABR_56(true, 56, "ABR - Average Bit Rate 56 kbps"),
|
ABR_56(true, 56, "ABR - Average Bit Rate 56 kbps"),
|
||||||
VBR_5(true, Lame.QUALITY_MIDDLE, "VBR - Middle Quality (5)"),
|
VBR_5(true, Lame.QUALITY_MIDDLE, "VBR - Variable Bit Rate - Better Quality"),
|
||||||
VBR_7(true, Lame.QUALITY_LOW, "VBR - Low Quality (7)");
|
VBR_7(true, Lame.QUALITY_LOW, "VBR - Variable Bit Rate - Good Quality");
|
||||||
|
|
||||||
private boolean mVariableBitRate;
|
private boolean mVariableBitRate;
|
||||||
private int mSetting;
|
private int mSetting;
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.audio.convert.thumbdv.message;
|
package io.github.dsheirer.audio.convert.thumbdv.message;
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.audio.convert.thumbdv.message.response;
|
package io.github.dsheirer.audio.convert.thumbdv.message.response;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* *****************************************************************************
|
||||||
* sdrtrunk
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
* *****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
package io.github.dsheirer.audio.playback;
|
package io.github.dsheirer.audio.playback;
|
||||||
|
|
||||||
@@ -30,7 +29,6 @@ import io.github.dsheirer.icon.IconModel;
|
|||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
|
||||||
import io.github.dsheirer.source.mixer.MixerChannelConfiguration;
|
import io.github.dsheirer.source.mixer.MixerChannelConfiguration;
|
||||||
import jiconfont.icons.font_awesome.FontAwesome;
|
import jiconfont.icons.font_awesome.FontAwesome;
|
||||||
import jiconfont.swing.IconFontSwing;
|
import jiconfont.swing.IconFontSwing;
|
||||||
@@ -69,7 +67,6 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
|
|||||||
|
|
||||||
private IconModel mIconModel;
|
private IconModel mIconModel;
|
||||||
private SettingsManager mSettingsManager;
|
private SettingsManager mSettingsManager;
|
||||||
private SourceManager mSourceManager;
|
|
||||||
private IAudioController mController;
|
private IAudioController mController;
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
@@ -78,11 +75,10 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
|
|||||||
private AudioChannelsPanel mAudioChannelsPanel;
|
private AudioChannelsPanel mAudioChannelsPanel;
|
||||||
|
|
||||||
public AudioPanel(IconModel iconModel, UserPreferences userPreferences, SettingsManager settingsManager,
|
public AudioPanel(IconModel iconModel, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||||
SourceManager sourceManager, IAudioController controller, AliasModel aliasModel)
|
IAudioController controller, AliasModel aliasModel)
|
||||||
{
|
{
|
||||||
mIconModel = iconModel;
|
mIconModel = iconModel;
|
||||||
mSettingsManager = settingsManager;
|
mSettingsManager = settingsManager;
|
||||||
mSourceManager = sourceManager;
|
|
||||||
mController = controller;
|
mController = controller;
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class BinaryMessage extends BitSet
|
|||||||
* Logical (ie constructed) size of this bitset, despite the actual size of
|
* Logical (ie constructed) size of this bitset, despite the actual size of
|
||||||
* the super bitset that this class is based on
|
* the super bitset that this class is based on
|
||||||
*/
|
*/
|
||||||
private int mSize = 0;
|
private int mSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the next fill index location, when adding bits to this bitset
|
* Pointer to the next fill index location, when adding bits to this bitset
|
||||||
@@ -43,21 +43,21 @@ public class BinaryMessage extends BitSet
|
|||||||
*/
|
*/
|
||||||
private int mPointer = 0;
|
private int mPointer = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Bitset that buffers bits added one at a time, up to the size of the this
|
|
||||||
* bitset.
|
|
||||||
*
|
|
||||||
* Note: the super class bitset behind this class may have a size larger
|
|
||||||
* that the size parameter specified.
|
|
||||||
* @param size
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used for temporary storage of CRC check results when we're passing this
|
* Used for temporary storage of CRC check results when we're passing this
|
||||||
* message to an EDAC function.
|
* message to an EDAC function.
|
||||||
*/
|
*/
|
||||||
private CRC mCRC;
|
private CRC mCRC;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a bitset that buffers bits added one at a time, up to the size
|
||||||
|
* of the this bitset.
|
||||||
|
* <p>
|
||||||
|
* Note: the super class bitset behind this class may have a size larger
|
||||||
|
* that the size parameter specified.
|
||||||
|
*
|
||||||
|
* @param size of constructed bitset
|
||||||
|
*/
|
||||||
public BinaryMessage(int size)
|
public BinaryMessage(int size)
|
||||||
{
|
{
|
||||||
super(size);
|
super(size);
|
||||||
@@ -214,9 +214,7 @@ public class BinaryMessage extends BitSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a (new) copy of this bitsetbuffer
|
* @return a (new) copy of this binary message
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public BinaryMessage copy()
|
public BinaryMessage copy()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* SDR Trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
package io.github.dsheirer.buffer;
|
package io.github.dsheirer.buffer;
|
||||||
|
|
||||||
import io.github.dsheirer.sample.complex.Complex;
|
import io.github.dsheirer.sample.complex.Complex;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2021 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.buffer;
|
package io.github.dsheirer.buffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.metadata;
|
package io.github.dsheirer.channel.metadata;
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.state;
|
package io.github.dsheirer.channel.state;
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.state;
|
package io.github.dsheirer.channel.state;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.state;
|
package io.github.dsheirer.channel.state;
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.state;
|
package io.github.dsheirer.channel.state;
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.channel.state;
|
package io.github.dsheirer.channel.state;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -30,8 +30,8 @@ import io.github.dsheirer.map.MapService;
|
|||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.source.tuner.TunerViewPanel;
|
import io.github.dsheirer.source.tuner.ui.TunerViewPanel;
|
||||||
import jiconfont.icons.font_awesome.FontAwesome;
|
import jiconfont.icons.font_awesome.FontAwesome;
|
||||||
import jiconfont.swing.IconFontSwing;
|
import jiconfont.swing.IconFontSwing;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@@ -59,13 +59,13 @@ public class ControllerPanel extends JPanel
|
|||||||
|
|
||||||
public ControllerPanel(PlaylistManager playlistManager, AudioPlaybackManager audioPlaybackManager,
|
public ControllerPanel(PlaylistManager playlistManager, AudioPlaybackManager audioPlaybackManager,
|
||||||
IconModel iconModel, MapService mapService, SettingsManager settingsManager,
|
IconModel iconModel, MapService mapService, SettingsManager settingsManager,
|
||||||
SourceManager sourceManager, UserPreferences userPreferences)
|
TunerManager tunerManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mAudioPanel = new AudioPanel(iconModel, userPreferences, settingsManager, sourceManager, audioPlaybackManager,
|
mAudioPanel = new AudioPanel(iconModel, userPreferences, settingsManager, audioPlaybackManager,
|
||||||
playlistManager.getAliasModel());
|
playlistManager.getAliasModel());
|
||||||
mNowPlayingPanel = new NowPlayingPanel(playlistManager, iconModel, userPreferences);
|
mNowPlayingPanel = new NowPlayingPanel(playlistManager, iconModel, userPreferences);
|
||||||
mMapPanel = new MapPanel(mapService, playlistManager.getAliasModel(), iconModel, settingsManager);
|
mMapPanel = new MapPanel(mapService, playlistManager.getAliasModel(), iconModel, settingsManager);
|
||||||
mTunerManagerPanel = new TunerViewPanel(sourceManager.getTunerModel(), userPreferences);
|
mTunerManagerPanel = new TunerViewPanel(tunerManager, userPreferences);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.controller.channel;
|
package io.github.dsheirer.controller.channel;
|
||||||
|
|
||||||
@@ -47,14 +44,15 @@ import io.github.dsheirer.sample.Listener;
|
|||||||
import io.github.dsheirer.source.Source;
|
import io.github.dsheirer.source.Source;
|
||||||
import io.github.dsheirer.source.SourceEvent;
|
import io.github.dsheirer.source.SourceEvent;
|
||||||
import io.github.dsheirer.source.SourceException;
|
import io.github.dsheirer.source.SourceException;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
|
||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -86,7 +84,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
private ChannelMapModel mChannelMapModel;
|
private ChannelMapModel mChannelMapModel;
|
||||||
private ChannelMetadataModel mChannelMetadataModel;
|
private ChannelMetadataModel mChannelMetadataModel;
|
||||||
private EventLogManager mEventLogManager;
|
private EventLogManager mEventLogManager;
|
||||||
private SourceManager mSourceManager;
|
private TunerManager mTunerManager;
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
private List<Long> mLoggedFrequencies = new ArrayList<>();
|
private List<Long> mLoggedFrequencies = new ArrayList<>();
|
||||||
@@ -97,16 +95,16 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
*
|
*
|
||||||
* @param channelMapModel containing channel maps defined by the user
|
* @param channelMapModel containing channel maps defined by the user
|
||||||
* @param eventLogManager for adding event loggers to channels
|
* @param eventLogManager for adding event loggers to channels
|
||||||
* @param sourceManager for obtaining a tuner channel source for the channel
|
* @param tunerManager for obtaining a tuner channel source for the channel
|
||||||
* @param aliasModel for aliasing of identifiers produced by the channel
|
* @param aliasModel for aliasing of identifiers produced by the channel
|
||||||
* @param userPreferences for user defined behavior and settings
|
* @param userPreferences for user defined behavior and settings
|
||||||
*/
|
*/
|
||||||
public ChannelProcessingManager(ChannelMapModel channelMapModel, EventLogManager eventLogManager,
|
public ChannelProcessingManager(ChannelMapModel channelMapModel, EventLogManager eventLogManager,
|
||||||
SourceManager sourceManager, AliasModel aliasModel, UserPreferences userPreferences)
|
TunerManager tunerManager, AliasModel aliasModel, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mChannelMapModel = channelMapModel;
|
mChannelMapModel = channelMapModel;
|
||||||
mEventLogManager = eventLogManager;
|
mEventLogManager = eventLogManager;
|
||||||
mSourceManager = sourceManager;
|
mTunerManager = tunerManager;
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
mChannelMetadataModel = new ChannelMetadataModel();
|
mChannelMetadataModel = new ChannelMetadataModel();
|
||||||
@@ -303,7 +301,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
source = mSourceManager.getSource(channel.getSourceConfiguration(),
|
source = mTunerManager.getSource(channel.getSourceConfiguration(),
|
||||||
channel.getDecodeConfiguration().getChannelSpecification());
|
channel.getDecodeConfiguration().getChannelSpecification());
|
||||||
}
|
}
|
||||||
catch(SourceException se)
|
catch(SourceException se)
|
||||||
@@ -439,8 +437,15 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
{
|
{
|
||||||
processingChain.start();
|
processingChain.start();
|
||||||
|
|
||||||
//This has to be done on the FX event thread when the playlist editor is constructed
|
if(GraphicsEnvironment.isHeadless())
|
||||||
Platform.runLater(() -> channel.setProcessing(true));
|
{
|
||||||
|
channel.setProcessing(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//This has to be done on the FX event thread when the playlist editor is constructed
|
||||||
|
Platform.runLater(() -> channel.setProcessing(true));
|
||||||
|
}
|
||||||
|
|
||||||
mChannelEventBroadcaster.broadcast(new ChannelEvent(channel, ChannelEvent.Event.NOTIFICATION_PROCESSING_START));
|
mChannelEventBroadcaster.broadcast(new ChannelEvent(channel, ChannelEvent.Event.NOTIFICATION_PROCESSING_START));
|
||||||
}
|
}
|
||||||
@@ -526,13 +531,20 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
*/
|
*/
|
||||||
private void stopProcessing(Channel channel) throws ChannelException
|
private void stopProcessing(Channel channel) throws ChannelException
|
||||||
{
|
{
|
||||||
//This has to be done on the FX event thread when the playlist editor is constructed
|
|
||||||
Platform.runLater(() -> channel.setProcessing(false));
|
|
||||||
|
|
||||||
ProcessingChain processingChain = removeProcessingChain(channel);
|
ProcessingChain processingChain = removeProcessingChain(channel);
|
||||||
|
|
||||||
if(processingChain != null)
|
if(processingChain != null)
|
||||||
{
|
{
|
||||||
|
if(GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
channel.setProcessing(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//This has to be done on the FX event thread when the playlist editor is constructed
|
||||||
|
Platform.runLater(() -> channel.setProcessing(false));
|
||||||
|
}
|
||||||
|
|
||||||
//Since the processing chain's source will block on stop(), throw it to the thread pool to run
|
//Since the processing chain's source will block on stop(), throw it to the thread pool to run
|
||||||
ThreadPool.CACHED.submit(() -> {
|
ThreadPool.CACHED.submit(() -> {
|
||||||
try
|
try
|
||||||
@@ -558,10 +570,6 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ChannelException("Channel is not currently playing");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -712,7 +720,9 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
{
|
{
|
||||||
@Override public void receive(SourceEvent sourceEvent)
|
@Override public void receive(SourceEvent sourceEvent)
|
||||||
{
|
{
|
||||||
if(sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_ERROR_STATE && sourceEvent.getSource() != null)
|
if((sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_ERROR_STATE ||
|
||||||
|
sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_TUNER_SHUTDOWN) &&
|
||||||
|
sourceEvent.getSource() != null)
|
||||||
{
|
{
|
||||||
Channel toShutdown = null;
|
Channel toShutdown = null;
|
||||||
|
|
||||||
@@ -736,7 +746,18 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
|||||||
|
|
||||||
if(toShutdown != null)
|
if(toShutdown != null)
|
||||||
{
|
{
|
||||||
mLog.warn("Channel source error detected - stopping channel [" + toShutdown.getName() + "]");
|
if(sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_ERROR_STATE)
|
||||||
|
{
|
||||||
|
mLog.warn("Channel source error detected - stopping channel [" + toShutdown.getName() + "]");
|
||||||
|
}
|
||||||
|
else if(sourceEvent.getEvent() == SourceEvent.Event.NOTIFICATION_TUNER_SHUTDOWN)
|
||||||
|
{
|
||||||
|
mLog.warn("Tuner removal detected - stopping channel [" + toShutdown.getName() + "]");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.warn("Source event error - stopping channel [" + toShutdown.getName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.apache.commons.math3.util.FastMath;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -84,6 +85,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
|||||||
private NativeBufferReceiver mNativeBufferReceiver = new NativeBufferReceiver();
|
private NativeBufferReceiver mNativeBufferReceiver = new NativeBufferReceiver();
|
||||||
private Dispatcher mBufferDispatcher;
|
private Dispatcher mBufferDispatcher;
|
||||||
private Map<Integer,float[]> mOutputProcessorFilters = new HashMap<>();
|
private Map<Integer,float[]> mOutputProcessorFilters = new HashMap<>();
|
||||||
|
private boolean mRunning = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a polyphase channel manager instance.
|
* Creates a polyphase channel manager instance.
|
||||||
@@ -126,6 +128,25 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
|||||||
this(tunerController, tunerController.getFrequency(), tunerController.getSampleRate());
|
this(tunerController, tunerController.getFrequency(), tunerController.getSampleRate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stopAllChannels()
|
||||||
|
{
|
||||||
|
mRunning = false;
|
||||||
|
|
||||||
|
List<TunerChannelSource> toStop = new ArrayList<>(mChannelSources);
|
||||||
|
|
||||||
|
for(TunerChannelSource tunerChannelSource: toStop)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
tunerChannelSource.process(SourceEvent.tunerShutdown(tunerChannelSource));
|
||||||
|
}
|
||||||
|
catch(SourceException se)
|
||||||
|
{
|
||||||
|
mLog.error("Error stopping tuner channel source for tuner shutdown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals to all provisioned tuner channel sources that the source complex buffer provider has an error and can
|
* Signals to all provisioned tuner channel sources that the source complex buffer provider has an error and can
|
||||||
* no longer provide channels, so that the tuner channel source can notify the consumer of the error state.
|
* no longer provide channels, so that the tuner channel source can notify the consumer of the error state.
|
||||||
@@ -164,24 +185,27 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
|||||||
{
|
{
|
||||||
PolyphaseChannelSource channelSource = null;
|
PolyphaseChannelSource channelSource = null;
|
||||||
|
|
||||||
List<Integer> polyphaseIndexes = mChannelCalculator.getChannelIndexes(tunerChannel);
|
if(mRunning)
|
||||||
|
|
||||||
IPolyphaseChannelOutputProcessor outputProcessor = getOutputProcessor(polyphaseIndexes);
|
|
||||||
|
|
||||||
if(outputProcessor != null)
|
|
||||||
{
|
{
|
||||||
long centerFrequency = mChannelCalculator.getCenterFrequencyForIndexes(polyphaseIndexes);
|
List<Integer> polyphaseIndexes = mChannelCalculator.getChannelIndexes(tunerChannel);
|
||||||
|
|
||||||
try
|
IPolyphaseChannelOutputProcessor outputProcessor = getOutputProcessor(polyphaseIndexes);
|
||||||
{
|
|
||||||
channelSource = new PolyphaseChannelSource(tunerChannel, outputProcessor, mChannelSourceEventListener,
|
|
||||||
mChannelCalculator.getChannelSampleRate(), centerFrequency);
|
|
||||||
|
|
||||||
mChannelSources.add(channelSource);
|
if(outputProcessor != null)
|
||||||
}
|
|
||||||
catch(FilterDesignException fde)
|
|
||||||
{
|
{
|
||||||
mLog.debug("Couldn't design final output low pass filter for polyphase channel source");
|
long centerFrequency = mChannelCalculator.getCenterFrequencyForIndexes(polyphaseIndexes);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
channelSource = new PolyphaseChannelSource(tunerChannel, outputProcessor, mChannelSourceEventListener,
|
||||||
|
mChannelCalculator.getChannelSampleRate(), centerFrequency);
|
||||||
|
|
||||||
|
mChannelSources.add(channelSource);
|
||||||
|
}
|
||||||
|
catch(FilterDesignException fde)
|
||||||
|
{
|
||||||
|
mLog.debug("Couldn't design final output low pass filter for polyphase channel source");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class DecimationFilterFactory
|
|||||||
*/
|
*/
|
||||||
public static int getDecimationRate(int requestedRate)
|
public static int getDecimationRate(int requestedRate)
|
||||||
{
|
{
|
||||||
if(requestedRate < 2)
|
if(requestedRate < 0)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Requested decimation rate must be greater than 2");
|
throw new IllegalArgumentException("Requested decimation rate must be greater than 2");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2021 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 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.dsp.filter.fir.remez;
|
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||||
|
|
||||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||||
|
|
||||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||||
|
|
||||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2021 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* SDR Trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
package io.github.dsheirer.edac;
|
package io.github.dsheirer.edac;
|
||||||
|
|
||||||
import io.github.dsheirer.bits.BinaryMessage;
|
import io.github.dsheirer.bits.BinaryMessage;
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class FilterEditorPanel<T> extends JPanel
|
|||||||
List<IFilter<T>> filters = filterSet.getFilters();
|
List<IFilter<T>> filters = filterSet.getFilters();
|
||||||
|
|
||||||
/* sort the filters in alphabetical order by name */
|
/* sort the filters in alphabetical order by name */
|
||||||
filters.sort((Comparator<IFilter<?>>) (first, second) -> first.getName().compareTo(second.getName()));
|
filters.sort(Comparator.comparing(IFilter::getName));
|
||||||
|
|
||||||
for(IFilter<T> filter : filters)
|
for(IFilter<T> filter : filters)
|
||||||
{
|
{
|
||||||
@@ -98,7 +98,7 @@ public class FilterEditorPanel<T> extends JPanel
|
|||||||
{
|
{
|
||||||
List<FilterElement<?>> elements = filter.getFilterElements();
|
List<FilterElement<?>> elements = filter.getFilterElements();
|
||||||
|
|
||||||
elements.sort(Comparator.comparing(FilterElement::toString));
|
elements.sort(Comparator.comparing(FilterElement::getName));
|
||||||
|
|
||||||
for(FilterElement<?> element : elements)
|
for(FilterElement<?> element : elements)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,13 +46,14 @@ public class FilterSet<T> implements IFilter<T>
|
|||||||
{
|
{
|
||||||
for( IFilter<T> filter: mFilters )
|
for( IFilter<T> filter: mFilters )
|
||||||
{
|
{
|
||||||
if( filter.canProcess( t ) )
|
// Make sure to loop through all filters.
|
||||||
|
// Only return if true or all filters have been evaluated.
|
||||||
|
if( filter.canProcess( t ) && filter.passes( t ))
|
||||||
{
|
{
|
||||||
return filter.passes( t );
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,7 @@ import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
|||||||
import io.github.dsheirer.module.log.EventLogManager;
|
import io.github.dsheirer.module.log.EventLogManager;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
|
||||||
import io.github.dsheirer.source.tuner.TunerModel;
|
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.embed.swing.JFXPanel;
|
import javafx.embed.swing.JFXPanel;
|
||||||
@@ -79,6 +76,7 @@ public class JavaFxWindowManager extends Application
|
|||||||
private JmbeEditor mJmbeEditor;
|
private JmbeEditor mJmbeEditor;
|
||||||
private PlaylistEditor mPlaylistEditor;
|
private PlaylistEditor mPlaylistEditor;
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
private TunerManager mTunerManager;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
private UserPreferencesEditor mUserPreferencesEditor;
|
private UserPreferencesEditor mUserPreferencesEditor;
|
||||||
|
|
||||||
@@ -91,9 +89,10 @@ public class JavaFxWindowManager extends Application
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance. Note: this constructor is used for Swing applications.
|
* Constructs an instance. Note: this constructor is used for Swing applications.
|
||||||
*/
|
*/
|
||||||
public JavaFxWindowManager(UserPreferences userPreferences, PlaylistManager playlistManager)
|
public JavaFxWindowManager(UserPreferences userPreferences, TunerManager tunerManager, PlaylistManager playlistManager)
|
||||||
{
|
{
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
|
mTunerManager = tunerManager;
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
@@ -106,12 +105,10 @@ public class JavaFxWindowManager extends Application
|
|||||||
{
|
{
|
||||||
mUserPreferences = new UserPreferences();
|
mUserPreferences = new UserPreferences();
|
||||||
AliasModel aliasModel = new AliasModel();
|
AliasModel aliasModel = new AliasModel();
|
||||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
|
||||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
|
||||||
SourceManager sourceManager = new SourceManager(tunerModel, new SettingsManager(tunerConfigurationModel),
|
|
||||||
mUserPreferences);
|
|
||||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||||
mPlaylistManager = new PlaylistManager(mUserPreferences, sourceManager, aliasModel, eventLogManager, new IconModel());
|
mTunerManager = new TunerManager(mUserPreferences);
|
||||||
|
mTunerManager.start();
|
||||||
|
mPlaylistManager = new PlaylistManager(mUserPreferences, mTunerManager, aliasModel, eventLogManager, new IconModel());
|
||||||
mPlaylistManager.init();
|
mPlaylistManager.init();
|
||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
@@ -274,7 +271,7 @@ public class JavaFxWindowManager extends Application
|
|||||||
{
|
{
|
||||||
if(mPlaylistEditor == null)
|
if(mPlaylistEditor == null)
|
||||||
{
|
{
|
||||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mUserPreferences);
|
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mPlaylistEditor;
|
return mPlaylistEditor;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
|||||||
import io.github.dsheirer.controller.ControllerPanel;
|
import io.github.dsheirer.controller.ControllerPanel;
|
||||||
import io.github.dsheirer.controller.channel.Channel;
|
import io.github.dsheirer.controller.channel.Channel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelAutoStartFrame;
|
import io.github.dsheirer.controller.channel.ChannelAutoStartFrame;
|
||||||
|
import io.github.dsheirer.controller.channel.ChannelException;
|
||||||
import io.github.dsheirer.controller.channel.ChannelSelectionManager;
|
import io.github.dsheirer.controller.channel.ChannelSelectionManager;
|
||||||
import io.github.dsheirer.eventbus.MyEventBus;
|
import io.github.dsheirer.eventbus.MyEventBus;
|
||||||
import io.github.dsheirer.gui.icon.ViewIconManagerRequest;
|
import io.github.dsheirer.gui.icon.ViewIconManagerRequest;
|
||||||
@@ -47,12 +48,11 @@ import io.github.dsheirer.properties.SystemProperties;
|
|||||||
import io.github.dsheirer.record.AudioRecordingManager;
|
import io.github.dsheirer.record.AudioRecordingManager;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
|
||||||
import io.github.dsheirer.source.tuner.Tuner;
|
import io.github.dsheirer.source.tuner.Tuner;
|
||||||
import io.github.dsheirer.source.tuner.TunerEvent;
|
import io.github.dsheirer.source.tuner.TunerEvent;
|
||||||
import io.github.dsheirer.source.tuner.TunerModel;
|
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
|
||||||
import io.github.dsheirer.source.tuner.TunerSpectralDisplayManager;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
import io.github.dsheirer.source.tuner.ui.TunerSpectralDisplayManager;
|
||||||
import io.github.dsheirer.spectrum.ClearTunerMenuItem;
|
import io.github.dsheirer.spectrum.ClearTunerMenuItem;
|
||||||
import io.github.dsheirer.spectrum.ShowTunerMenuItem;
|
import io.github.dsheirer.spectrum.ShowTunerMenuItem;
|
||||||
import io.github.dsheirer.spectrum.SpectralDisplayPanel;
|
import io.github.dsheirer.spectrum.SpectralDisplayPanel;
|
||||||
@@ -68,11 +68,25 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.JCheckBoxMenuItem;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuBar;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JSeparator;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.event.MenuEvent;
|
import javax.swing.event.MenuEvent;
|
||||||
import javax.swing.event.MenuListener;
|
import javax.swing.event.MenuListener;
|
||||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||||
import java.awt.*;
|
import java.awt.AWTException;
|
||||||
|
import java.awt.Desktop;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Robot;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
@@ -104,19 +118,24 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
private ControllerPanel mControllerPanel;
|
private ControllerPanel mControllerPanel;
|
||||||
private IconModel mIconModel = new IconModel();
|
private IconModel mIconModel = new IconModel();
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
private SourceManager mSourceManager;
|
|
||||||
private SettingsManager mSettingsManager;
|
private SettingsManager mSettingsManager;
|
||||||
private SpectralDisplayPanel mSpectralPanel;
|
private SpectralDisplayPanel mSpectralPanel;
|
||||||
private JFrame mMainGui = new JFrame();
|
private JFrame mMainGui;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
private JavaFxWindowManager mJavaFxWindowManager;
|
private JavaFxWindowManager mJavaFxWindowManager;
|
||||||
private UserPreferences mUserPreferences = new UserPreferences();
|
private UserPreferences mUserPreferences = new UserPreferences();
|
||||||
|
private TunerManager mTunerManager;
|
||||||
private ApplicationLog mApplicationLog;
|
private ApplicationLog mApplicationLog;
|
||||||
|
|
||||||
private String mTitle;
|
private String mTitle;
|
||||||
|
|
||||||
public SDRTrunk()
|
public SDRTrunk()
|
||||||
{
|
{
|
||||||
|
if(!GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
mMainGui = new JFrame();
|
||||||
|
}
|
||||||
|
|
||||||
mApplicationLog = new ApplicationLog(mUserPreferences);
|
mApplicationLog = new ApplicationLog(mUserPreferences);
|
||||||
mApplicationLog.start();
|
mApplicationLog.start();
|
||||||
|
|
||||||
@@ -154,16 +173,19 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
//Register FontAwesome so we can use the fonts in Swing windows
|
//Register FontAwesome so we can use the fonts in Swing windows
|
||||||
IconFontSwing.register(FontAwesome.getIconFont());
|
IconFontSwing.register(FontAwesome.getIconFont());
|
||||||
|
|
||||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
mTunerManager = new TunerManager(mUserPreferences);
|
||||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
mTunerManager.start();
|
||||||
|
|
||||||
mSettingsManager = new SettingsManager(tunerConfigurationModel);
|
mSettingsManager = new SettingsManager();
|
||||||
mSourceManager = new SourceManager(tunerModel, mSettingsManager, mUserPreferences);
|
|
||||||
|
|
||||||
AliasModel aliasModel = new AliasModel();
|
AliasModel aliasModel = new AliasModel();
|
||||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||||
mPlaylistManager = new PlaylistManager(mUserPreferences, mSourceManager, aliasModel, eventLogManager, mIconModel);
|
mPlaylistManager = new PlaylistManager(mUserPreferences, mTunerManager, aliasModel, eventLogManager, mIconModel);
|
||||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mPlaylistManager);
|
|
||||||
|
if(!GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mTunerManager, mPlaylistManager);
|
||||||
|
}
|
||||||
|
|
||||||
CalibrationManager calibrationManager = CalibrationManager.getInstance(mUserPreferences);
|
CalibrationManager calibrationManager = CalibrationManager.getInstance(mUserPreferences);
|
||||||
final boolean calibrating = !calibrationManager.isCalibrated() &&
|
final boolean calibrating = !calibrationManager.isCalibrated() &&
|
||||||
@@ -190,32 +212,45 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
MapService mapService = new MapService(mIconModel);
|
MapService mapService = new MapService(mIconModel);
|
||||||
mPlaylistManager.getChannelProcessingManager().addDecodeEventListener(mapService);
|
mPlaylistManager.getChannelProcessingManager().addDecodeEventListener(mapService);
|
||||||
|
|
||||||
mControllerPanel = new ControllerPanel(mPlaylistManager, audioPlaybackManager, mIconModel, mapService,
|
if(!GraphicsEnvironment.isHeadless())
|
||||||
mSettingsManager, mSourceManager, mUserPreferences);
|
{
|
||||||
|
mControllerPanel = new ControllerPanel(mPlaylistManager, audioPlaybackManager, mIconModel, mapService,
|
||||||
|
mSettingsManager, mTunerManager, mUserPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
mSpectralPanel = new SpectralDisplayPanel(mPlaylistManager, mSettingsManager, tunerModel);
|
mSpectralPanel = new SpectralDisplayPanel(mPlaylistManager, mSettingsManager, mTunerManager.getDiscoveredTunerModel());
|
||||||
|
|
||||||
TunerSpectralDisplayManager tunerSpectralDisplayManager = new TunerSpectralDisplayManager(mSpectralPanel,
|
TunerSpectralDisplayManager tunerSpectralDisplayManager = new TunerSpectralDisplayManager(mSpectralPanel,
|
||||||
mPlaylistManager, mSettingsManager, tunerModel);
|
mPlaylistManager, mSettingsManager, mTunerManager.getDiscoveredTunerModel());
|
||||||
tunerModel.addListener(tunerSpectralDisplayManager);
|
mTunerManager.getDiscoveredTunerModel().addListener(tunerSpectralDisplayManager);
|
||||||
tunerModel.addListener(this);
|
mTunerManager.getDiscoveredTunerModel().addListener(this);
|
||||||
|
|
||||||
mPlaylistManager.init();
|
mPlaylistManager.init();
|
||||||
|
|
||||||
mLog.info("starting main application gui");
|
if(GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
mLog.info("starting main application headless");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.info("starting main application gui");
|
||||||
|
|
||||||
//Initialize the GUI
|
//Initialize the GUI
|
||||||
initGUI();
|
initGUI();
|
||||||
|
}
|
||||||
tunerModel.requestFirstTunerDisplay();
|
|
||||||
|
|
||||||
//Start the gui
|
//Start the gui
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mMainGui.setVisible(true);
|
if(!GraphicsEnvironment.isHeadless())
|
||||||
|
{
|
||||||
|
mMainGui.setVisible(true);
|
||||||
|
Tuner tuner = tunerSpectralDisplayManager.showFirstTuner();
|
||||||
|
updateTitle(tuner);
|
||||||
|
}
|
||||||
|
|
||||||
if(calibrating)
|
if(calibrating && !GraphicsEnvironment.isHeadless())
|
||||||
{
|
{
|
||||||
Platform.runLater(() ->
|
Platform.runLater(() ->
|
||||||
{
|
{
|
||||||
@@ -256,8 +291,25 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
|
|
||||||
if(channels.size() > 0)
|
if(channels.size() > 0)
|
||||||
{
|
{
|
||||||
ChannelAutoStartFrame autoStartFrame = new ChannelAutoStartFrame(mPlaylistManager.getChannelProcessingManager(),
|
if(GraphicsEnvironment.isHeadless())
|
||||||
channels);
|
{
|
||||||
|
for(Channel channel: channels)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mLog.info("Auto-starting channel " + channel.getName());
|
||||||
|
mPlaylistManager.getChannelProcessingManager().start(channel);
|
||||||
|
}
|
||||||
|
catch(ChannelException ce)
|
||||||
|
{
|
||||||
|
mLog.error("Channel: " + channel.getName() + " auto-start failed: " + ce.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new ChannelAutoStartFrame(mPlaylistManager.getChannelProcessingManager(), channels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +507,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
|
|
||||||
mLog.info("Stopping spectral display ...");
|
mLog.info("Stopping spectral display ...");
|
||||||
mSpectralPanel.clearTuner();
|
mSpectralPanel.clearTuner();
|
||||||
mSourceManager.shutdown();
|
mLog.info("Stopping tuners ...");
|
||||||
|
mTunerManager.stop();
|
||||||
mLog.info("Shutdown complete.");
|
mLog.info("Shutdown complete.");
|
||||||
mApplicationLog.stop();
|
mApplicationLog.stop();
|
||||||
}
|
}
|
||||||
@@ -572,7 +625,23 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
{
|
{
|
||||||
if(event.getEvent() == TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY)
|
if(event.getEvent() == TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY)
|
||||||
{
|
{
|
||||||
mMainGui.setTitle(mTitle + " - " + event.getTuner().getName());
|
updateTitle(event.getTuner());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the title bar with the tuner name
|
||||||
|
* @param tuner optional
|
||||||
|
*/
|
||||||
|
private void updateTitle(Tuner tuner)
|
||||||
|
{
|
||||||
|
if(tuner != null)
|
||||||
|
{
|
||||||
|
mMainGui.setTitle(mTitle + " - " + tuner.getPreferredName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainGui.setTitle(mTitle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,9 +691,9 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
{
|
{
|
||||||
removeAll();
|
removeAll();
|
||||||
|
|
||||||
for(Tuner tuner : mSourceManager.getTunerModel().getTuners())
|
for(DiscoveredTuner discoveredTuner: mTunerManager.getAvailableTuners())
|
||||||
{
|
{
|
||||||
add(new ShowTunerMenuItem(mSourceManager.getTunerModel(), tuner));
|
add(new ShowTunerMenuItem(mTunerManager.getDiscoveredTunerModel(), discoveredTuner.getTuner()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,16 @@ package io.github.dsheirer.gui.channelizer;
|
|||||||
|
|
||||||
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
||||||
import io.github.dsheirer.buffer.INativeBuffer;
|
import io.github.dsheirer.buffer.INativeBuffer;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||||
import io.github.dsheirer.source.SourceEvent;
|
import io.github.dsheirer.source.SourceEvent;
|
||||||
import io.github.dsheirer.source.SourceException;
|
import io.github.dsheirer.source.SourceException;
|
||||||
|
import io.github.dsheirer.source.tuner.LoggingTunerErrorListener;
|
||||||
import io.github.dsheirer.source.tuner.Tuner;
|
import io.github.dsheirer.source.tuner.Tuner;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import io.github.dsheirer.source.tuner.test.TestTuner;
|
import io.github.dsheirer.source.tuner.test.TestTuner;
|
||||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||||
import io.github.dsheirer.spectrum.DFTSize;
|
import io.github.dsheirer.spectrum.DFTSize;
|
||||||
@@ -40,10 +39,16 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
|
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.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -57,7 +62,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
private static final int CHANNEL_BANDWIDTH = 12500;
|
private static final int CHANNEL_BANDWIDTH = 12500;
|
||||||
private static final int CHANNEL_FFT_FRAME_RATE = 20;
|
private static final int CHANNEL_FFT_FRAME_RATE = 20;
|
||||||
|
|
||||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
private SettingsManager mSettingsManager = new SettingsManager();
|
||||||
private JPanel mPrimaryPanel;
|
private JPanel mPrimaryPanel;
|
||||||
private JPanel mControlPanel;
|
private JPanel mControlPanel;
|
||||||
private JLabel mToneFrequencyLabel;
|
private JLabel mToneFrequencyLabel;
|
||||||
@@ -78,7 +83,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
*/
|
*/
|
||||||
public ChannelizerViewer(int channelsPerRow)
|
public ChannelizerViewer(int channelsPerRow)
|
||||||
{
|
{
|
||||||
mTestTuner = new TestTuner(new UserPreferences());
|
mTestTuner = new TestTuner(new LoggingTunerErrorListener());
|
||||||
mChannelCount = (int)(mTestTuner.getTunerController().getBandwidth() / CHANNEL_BANDWIDTH);
|
mChannelCount = (int)(mTestTuner.getTunerController().getBandwidth() / CHANNEL_BANDWIDTH);
|
||||||
mChannelsPerRow = channelsPerRow;
|
mChannelsPerRow = channelsPerRow;
|
||||||
|
|
||||||
@@ -518,7 +523,7 @@ public class ChannelizerViewer extends JFrame
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TestTuner tuner = new TestTuner(new UserPreferences());
|
TestTuner tuner = new TestTuner(new LoggingTunerErrorListener());
|
||||||
|
|
||||||
List<TunerChannel> tunerChannels = getTunerChannels(tuner);
|
List<TunerChannel> tunerChannels = getTunerChannels(tuner);
|
||||||
|
|
||||||
|
|||||||
@@ -20,18 +20,17 @@ package io.github.dsheirer.gui.channelizer;
|
|||||||
|
|
||||||
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
||||||
import io.github.dsheirer.buffer.INativeBuffer;
|
import io.github.dsheirer.buffer.INativeBuffer;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||||
import io.github.dsheirer.source.SourceEvent;
|
import io.github.dsheirer.source.SourceEvent;
|
||||||
import io.github.dsheirer.source.SourceException;
|
import io.github.dsheirer.source.SourceException;
|
||||||
|
import io.github.dsheirer.source.tuner.LoggingTunerErrorListener;
|
||||||
import io.github.dsheirer.source.tuner.Tuner;
|
import io.github.dsheirer.source.tuner.Tuner;
|
||||||
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import io.github.dsheirer.source.tuner.test.TestTuner;
|
import io.github.dsheirer.source.tuner.test.TestTuner;
|
||||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||||
import io.github.dsheirer.spectrum.DFTSize;
|
import io.github.dsheirer.spectrum.DFTSize;
|
||||||
@@ -41,10 +40,18 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
|
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.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -56,7 +63,7 @@ public class ChannelizerViewer2 extends JFrame
|
|||||||
|
|
||||||
private static final int CHANNEL_BANDWIDTH = 12500;
|
private static final int CHANNEL_BANDWIDTH = 12500;
|
||||||
|
|
||||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
private SettingsManager mSettingsManager = new SettingsManager();
|
||||||
private JPanel mPrimaryPanel;
|
private JPanel mPrimaryPanel;
|
||||||
private JPanel mControlPanel;
|
private JPanel mControlPanel;
|
||||||
private JButton mTopFrameAddChannelButton;
|
private JButton mTopFrameAddChannelButton;
|
||||||
@@ -68,7 +75,7 @@ public class ChannelizerViewer2 extends JFrame
|
|||||||
private ChannelArrayPanel mBottomChannelArrayPanel;
|
private ChannelArrayPanel mBottomChannelArrayPanel;
|
||||||
private DFTSize mMainPanelDFTSize = DFTSize.FFT32768;
|
private DFTSize mMainPanelDFTSize = DFTSize.FFT32768;
|
||||||
private DFTSize mChannelPanelDFTSize = DFTSize.FFT04096;
|
private DFTSize mChannelPanelDFTSize = DFTSize.FFT04096;
|
||||||
private TestTuner mTestTuner = new TestTuner(new UserPreferences());
|
private TestTuner mTestTuner = new TestTuner(new LoggingTunerErrorListener());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GUI Test utility for researching polyphase channelizers.
|
* GUI Test utility for researching polyphase channelizers.
|
||||||
|
|||||||
@@ -20,18 +20,17 @@ package io.github.dsheirer.gui.channelizer;
|
|||||||
|
|
||||||
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
||||||
import io.github.dsheirer.buffer.INativeBuffer;
|
import io.github.dsheirer.buffer.INativeBuffer;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||||
import io.github.dsheirer.source.SourceEvent;
|
import io.github.dsheirer.source.SourceEvent;
|
||||||
import io.github.dsheirer.source.SourceException;
|
import io.github.dsheirer.source.SourceException;
|
||||||
|
import io.github.dsheirer.source.tuner.LoggingTunerErrorListener;
|
||||||
import io.github.dsheirer.source.tuner.Tuner;
|
import io.github.dsheirer.source.tuner.Tuner;
|
||||||
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import io.github.dsheirer.source.tuner.test.TestTuner;
|
import io.github.dsheirer.source.tuner.test.TestTuner;
|
||||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||||
import io.github.dsheirer.spectrum.DFTSize;
|
import io.github.dsheirer.spectrum.DFTSize;
|
||||||
@@ -41,10 +40,16 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
|
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.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -58,7 +63,7 @@ public class HeterodyneChannelizerViewer extends JFrame
|
|||||||
private static final int CHANNEL_BANDWIDTH = 12500;
|
private static final int CHANNEL_BANDWIDTH = 12500;
|
||||||
private static final int CHANNEL_FFT_FRAME_RATE = 20;
|
private static final int CHANNEL_FFT_FRAME_RATE = 20;
|
||||||
|
|
||||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
private SettingsManager mSettingsManager = new SettingsManager();
|
||||||
private JPanel mPrimaryPanel;
|
private JPanel mPrimaryPanel;
|
||||||
private JPanel mControlPanel;
|
private JPanel mControlPanel;
|
||||||
private JLabel mToneFrequencyLabel;
|
private JLabel mToneFrequencyLabel;
|
||||||
@@ -77,7 +82,7 @@ public class HeterodyneChannelizerViewer extends JFrame
|
|||||||
*/
|
*/
|
||||||
public HeterodyneChannelizerViewer()
|
public HeterodyneChannelizerViewer()
|
||||||
{
|
{
|
||||||
mTestTuner = new TestTuner(new UserPreferences());
|
mTestTuner = new TestTuner(new LoggingTunerErrorListener());
|
||||||
mChannelCount = 5;
|
mChannelCount = 5;
|
||||||
mChannelsPerRow = 5;
|
mChannelsPerRow = 5;
|
||||||
init();
|
init();
|
||||||
@@ -516,7 +521,7 @@ public class HeterodyneChannelizerViewer extends JFrame
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TestTuner tuner = new TestTuner(new UserPreferences());
|
TestTuner tuner = new TestTuner(new LoggingTunerErrorListener());
|
||||||
|
|
||||||
List<TunerChannel> tunerChannels = getTunerChannels(tuner);
|
List<TunerChannel> tunerChannels = getTunerChannels(tuner);
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import io.github.dsheirer.dsp.oscillator.OscillatorFactory;
|
|||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.settings.SettingsManager;
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||||
import io.github.dsheirer.spectrum.DFTSize;
|
import io.github.dsheirer.spectrum.DFTSize;
|
||||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||||
@@ -39,10 +38,15 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import java.awt.*;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class SynthesizerViewer extends JFrame
|
public class SynthesizerViewer extends JFrame
|
||||||
@@ -54,7 +58,7 @@ public class SynthesizerViewer extends JFrame
|
|||||||
private static final int CHANNEL_FFT_FRAME_RATE = 20; //frames per second
|
private static final int CHANNEL_FFT_FRAME_RATE = 20; //frames per second
|
||||||
private static final int DATA_GENERATOR_FRAME_RATE = 50; //frames per second
|
private static final int DATA_GENERATOR_FRAME_RATE = 50; //frames per second
|
||||||
|
|
||||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
private SettingsManager mSettingsManager = new SettingsManager();
|
||||||
private JPanel mPrimaryPanel;
|
private JPanel mPrimaryPanel;
|
||||||
private PrimarySpectrumPanel mPrimarySpectrumPanel;
|
private PrimarySpectrumPanel mPrimarySpectrumPanel;
|
||||||
private ChannelPanel mChannel1Panel;
|
private ChannelPanel mChannel1Panel;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdrtrunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,7 +14,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
package io.github.dsheirer.gui.control;
|
package io.github.dsheirer.gui.control;
|
||||||
|
|
||||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||||
@@ -69,12 +70,6 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JFrequencyControl(long value)
|
|
||||||
{
|
|
||||||
this();
|
|
||||||
mFrequency = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[]0[]", ""));
|
setLayout(new MigLayout("insets 0 0 0 0", "[]0[]", ""));
|
||||||
@@ -91,8 +86,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
}
|
}
|
||||||
catch(ParseException e)
|
catch(ParseException e)
|
||||||
{
|
{
|
||||||
mLog.error("JFrequencyControl - parse exception "
|
mLog.error("JFrequencyControl - parse exception constructing a digit - " + e);
|
||||||
+ "constructing a digit - " + e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(digit != null)
|
if(digit != null)
|
||||||
@@ -105,15 +99,11 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
|
|
||||||
if(x == 6)
|
if(x == 6)
|
||||||
{
|
{
|
||||||
JLabel period = new JLabel(".");
|
add(new JLabel(". "));
|
||||||
|
|
||||||
add(period);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add(new JLabel(" MHz"));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a blank cursor to use when the mouse is over the digits
|
* Create a blank cursor to use when the mouse is over the digits
|
||||||
*/
|
*/
|
||||||
@@ -123,11 +113,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
//Create image for cursor using empty array
|
//Create image for cursor using empty array
|
||||||
Image cursorImage = Toolkit.getDefaultToolkit().createImage(imageByte);
|
Image cursorImage = Toolkit.getDefaultToolkit().createImage(imageByte);
|
||||||
|
|
||||||
mBlankCursor = Toolkit.getDefaultToolkit()
|
mBlankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new Point(0, 0), "cursor");
|
||||||
.createCustomCursor(cursorImage, new Point(0, 0), "cursor");
|
|
||||||
|
|
||||||
setTooltip(false);
|
|
||||||
|
|
||||||
revalidate();
|
revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,26 +128,6 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setTooltip(boolean locked)
|
|
||||||
{
|
|
||||||
String tooltip = null;
|
|
||||||
|
|
||||||
if(locked)
|
|
||||||
{
|
|
||||||
tooltip = "Frequency control is locked. Disable decoding channels to unlock.";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tooltip = "Click on a frequency digit and type a frequency value, or click the upper/lower digits to " +
|
|
||||||
"change the value";
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Digit digit: mDigits.values())
|
|
||||||
{
|
|
||||||
digit.setToolTipText(tooltip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives a frequency change event invoked by another control. We don't
|
* Receives a frequency change event invoked by another control. We don't
|
||||||
* rebroadcast this event, just set the control to indicate the new frequency.
|
* rebroadcast this event, just set the control to indicate the new frequency.
|
||||||
@@ -172,36 +138,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
switch(event.getEvent())
|
switch(event.getEvent())
|
||||||
{
|
{
|
||||||
case NOTIFICATION_FREQUENCY_CHANGE:
|
case NOTIFICATION_FREQUENCY_CHANGE:
|
||||||
EventQueue.invokeLater(new Runnable()
|
EventQueue.invokeLater(() -> setFrequency(event.getValue().longValue(), false));
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
setFrequency(event.getValue().longValue(), false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case NOTIFICATION_FREQUENCY_AND_SAMPLE_RATE_LOCKED:
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
setEnabled(false);
|
|
||||||
setTooltip(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case NOTIFICATION_FREQUENCY_AND_SAMPLE_RATE_UNLOCKED:
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
setEnabled(true);
|
|
||||||
setTooltip(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,11 +188,30 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the source event listener
|
||||||
|
* @param processor
|
||||||
|
*/
|
||||||
public void addListener(ISourceEventProcessor processor)
|
public void addListener(ISourceEventProcessor processor)
|
||||||
{
|
{
|
||||||
mProcessors.add(processor);
|
if(!mProcessors.contains(processor))
|
||||||
|
{
|
||||||
|
mProcessors.add(processor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all source event processors
|
||||||
|
*/
|
||||||
|
public void clearListeners()
|
||||||
|
{
|
||||||
|
mProcessors.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the source event processor
|
||||||
|
* @param processor
|
||||||
|
*/
|
||||||
public void removeListener(ISourceEventProcessor processor)
|
public void removeListener(ISourceEventProcessor processor)
|
||||||
{
|
{
|
||||||
mProcessors.remove(processor);
|
mProcessors.remove(processor);
|
||||||
@@ -272,7 +228,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
super("0");
|
super("0");
|
||||||
|
|
||||||
mPower = position;
|
mPower = position;
|
||||||
|
setToolTipText(getTooltip(mPower));
|
||||||
Listener listener = new Listener();
|
Listener listener = new Listener();
|
||||||
|
|
||||||
this.addKeyListener(listener);
|
this.addKeyListener(listener);
|
||||||
@@ -280,6 +236,49 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
|||||||
this.addMouseWheelListener(listener);
|
this.addMouseWheelListener(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getTooltip(int power)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Center frequency ");
|
||||||
|
switch(power)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
sb.append("1 Hertz");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sb.append("10 Hertz");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sb.append("100 Hertz");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sb.append("1 Kilohertz");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sb.append("10 Kilohertz");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
sb.append("100 Kilohertz");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
sb.append("1 Megahertz");
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
sb.append("10 Megahertz");
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
sb.append("100 Megahertz");
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
sb.append("1 Gigahertz");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(" units. Type a number, use up/down arrows, or click the upper/lower digit control to adjust");
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this digit to the value of the column in frequency that corresponds
|
* Sets this digit to the value of the column in frequency that corresponds
|
||||||
* to the power (ie column) set for this digit. Optionally, fires a
|
* to the power (ie column) set for this digit. Optionally, fires a
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
package io.github.dsheirer.gui.editor;
|
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
|
|
||||||
public class EmptyEditor<T> extends Editor<T>
|
|
||||||
{
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
public EmptyEditor( String descriptor )
|
|
||||||
{
|
|
||||||
setLayout( new MigLayout( "insets 0 0 0 0", "[center]", "[grow]" ) );
|
|
||||||
add( new JLabel( "Please select " + descriptor ), "wrap" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public EmptyEditor()
|
|
||||||
{
|
|
||||||
this( "an item" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void save()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* *****************************************************************************
|
||||||
* sdrtrunk
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
* Copyright (C) 2014-2019 Dennis Sheirer
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
* *****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
package io.github.dsheirer.gui.instrument.decoder;
|
package io.github.dsheirer.gui.instrument.decoder;
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
|||||||
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import io.github.dsheirer.util.TimeStamp;
|
import io.github.dsheirer.util.TimeStamp;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
@@ -65,6 +66,7 @@ public class PlaylistEditor extends BorderPane
|
|||||||
private static final Logger mLog = LoggerFactory.getLogger(PlaylistEditor.class);
|
private static final Logger mLog = LoggerFactory.getLogger(PlaylistEditor.class);
|
||||||
|
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
private TunerManager mTunerManager;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
private MenuBar mMenuBar;
|
private MenuBar mMenuBar;
|
||||||
private TabPane mTabPane;
|
private TabPane mTabPane;
|
||||||
@@ -79,11 +81,13 @@ public class PlaylistEditor extends BorderPane
|
|||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager for alias and channel models
|
* @param playlistManager for alias and channel models
|
||||||
|
* @param tunerManager for tuners
|
||||||
* @param userPreferences for settings
|
* @param userPreferences for settings
|
||||||
*/
|
*/
|
||||||
public PlaylistEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public PlaylistEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
|
mTunerManager = tunerManager;
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
//Throw a new runnable back onto the FX thread to lazy load the editor content after the editor has been
|
//Throw a new runnable back onto the FX thread to lazy load the editor content after the editor has been
|
||||||
@@ -240,7 +244,7 @@ public class PlaylistEditor extends BorderPane
|
|||||||
{
|
{
|
||||||
if(mChannelEditor == null)
|
if(mChannelEditor == null)
|
||||||
{
|
{
|
||||||
mChannelEditor = new ChannelEditor(mPlaylistManager, mUserPreferences);
|
mChannelEditor = new ChannelEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mChannelEditor;
|
return mChannelEditor;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -20,17 +20,12 @@
|
|||||||
package io.github.dsheirer.gui.playlist;
|
package io.github.dsheirer.gui.playlist;
|
||||||
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
|
||||||
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
|
||||||
import io.github.dsheirer.gui.JavaFxWindowManager;
|
import io.github.dsheirer.gui.JavaFxWindowManager;
|
||||||
import io.github.dsheirer.icon.IconModel;
|
import io.github.dsheirer.icon.IconModel;
|
||||||
import io.github.dsheirer.module.log.EventLogManager;
|
import io.github.dsheirer.module.log.EventLogManager;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.settings.SettingsManager;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
|
||||||
import io.github.dsheirer.source.tuner.TunerModel;
|
|
||||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
@@ -43,6 +38,7 @@ public class PlaylistEditorApplication extends Application
|
|||||||
{
|
{
|
||||||
private Stage mStage;
|
private Stage mStage;
|
||||||
private Parent mPlaylistEditor;
|
private Parent mPlaylistEditor;
|
||||||
|
private TunerManager mTunerManager;
|
||||||
private UserPreferences mUserPreferences = new UserPreferences();
|
private UserPreferences mUserPreferences = new UserPreferences();
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
private JavaFxWindowManager mJavaFxWindowManager;
|
private JavaFxWindowManager mJavaFxWindowManager;
|
||||||
@@ -50,17 +46,13 @@ public class PlaylistEditorApplication extends Application
|
|||||||
public PlaylistEditorApplication()
|
public PlaylistEditorApplication()
|
||||||
{
|
{
|
||||||
AliasModel aliasModel = new AliasModel();
|
AliasModel aliasModel = new AliasModel();
|
||||||
BroadcastModel broadcastModel = new BroadcastModel(aliasModel, new IconModel(), mUserPreferences);
|
|
||||||
ChannelMapModel channelMapModel = new ChannelMapModel();
|
|
||||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
|
||||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
|
||||||
SourceManager sourceManager = new SourceManager(tunerModel, new SettingsManager(tunerConfigurationModel),
|
|
||||||
mUserPreferences);
|
|
||||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||||
mPlaylistManager = new PlaylistManager(mUserPreferences, sourceManager, aliasModel, eventLogManager, new IconModel());
|
mTunerManager = new TunerManager(mUserPreferences);
|
||||||
|
mTunerManager.start();
|
||||||
|
mPlaylistManager = new PlaylistManager(mUserPreferences, mTunerManager, aliasModel, eventLogManager, new IconModel());
|
||||||
|
|
||||||
mPlaylistManager.init();
|
mPlaylistManager.init();
|
||||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mPlaylistManager);
|
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mTunerManager, mPlaylistManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,7 +69,7 @@ public class PlaylistEditorApplication extends Application
|
|||||||
{
|
{
|
||||||
if(mPlaylistEditor == null)
|
if(mPlaylistEditor == null)
|
||||||
{
|
{
|
||||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mUserPreferences);
|
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mPlaylistEditor;
|
return mPlaylistEditor;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -34,6 +31,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@@ -59,11 +57,14 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public AMConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public AMConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getRecordPane());
|
getTitledPanesBox().getChildren().add(getRecordPane());
|
||||||
@@ -138,7 +139,7 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
import io.github.dsheirer.source.tuner.TunerModel;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.util.ThreadPool;
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
@@ -80,6 +80,7 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelConfigurationEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ChannelConfigurationEditor.class);
|
||||||
|
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
protected TunerManager mTunerManager;
|
||||||
protected UserPreferences mUserPreferences;
|
protected UserPreferences mUserPreferences;
|
||||||
protected EditorModificationListener mEditorModificationListener = new EditorModificationListener();
|
protected EditorModificationListener mEditorModificationListener = new EditorModificationListener();
|
||||||
private Button mPlayButton;
|
private Button mPlayButton;
|
||||||
@@ -100,9 +101,17 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
private IconNode mStopGraphicNode;
|
private IconNode mStopGraphicNode;
|
||||||
private ChannelProcessingMonitor mChannelProcessingMonitor = new ChannelProcessingMonitor();
|
private ChannelProcessingMonitor mChannelProcessingMonitor = new ChannelProcessingMonitor();
|
||||||
|
|
||||||
public ChannelConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
/**
|
||||||
|
* Constructs an instance
|
||||||
|
* @param playlistManager for playlists
|
||||||
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
|
*/
|
||||||
|
public ChannelConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
|
mTunerManager = tunerManager;
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
setMaxWidth(Double.MAX_VALUE);
|
setMaxWidth(Double.MAX_VALUE);
|
||||||
@@ -236,11 +245,6 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
|||||||
modifiedProperty().setValue(false);
|
modifiedProperty().setValue(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TunerModel getTunerModel()
|
|
||||||
{
|
|
||||||
return mPlaylistManager.getTunerModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save()
|
public void save()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -25,6 +22,7 @@ package io.github.dsheirer.gui.playlist.channel;
|
|||||||
import io.github.dsheirer.module.decode.DecoderType;
|
import io.github.dsheirer.module.decode.DecoderType;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -46,28 +44,28 @@ public class ChannelConfigurationEditorFactory
|
|||||||
* @return constructed editor
|
* @return constructed editor
|
||||||
*/
|
*/
|
||||||
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager,
|
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager,
|
||||||
UserPreferences userPreferences)
|
TunerManager tunerManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
switch(decoderType)
|
switch(decoderType)
|
||||||
{
|
{
|
||||||
case AM:
|
case AM:
|
||||||
return new AMConfigurationEditor(playlistManager, userPreferences);
|
return new AMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case DMR:
|
case DMR:
|
||||||
return new DMRConfigurationEditor(playlistManager, userPreferences);
|
return new DMRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case NBFM:
|
case NBFM:
|
||||||
return new NBFMConfigurationEditor(playlistManager, userPreferences);
|
return new NBFMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case LTR_NET:
|
case LTR_NET:
|
||||||
return new LTRNetConfigurationEditor(playlistManager, userPreferences);
|
return new LTRNetConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case LTR:
|
case LTR:
|
||||||
return new LTRConfigurationEditor(playlistManager, userPreferences);
|
return new LTRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case MPT1327:
|
case MPT1327:
|
||||||
return new MPT1327ConfigurationEditor(playlistManager, userPreferences);
|
return new MPT1327ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case PASSPORT:
|
case PASSPORT:
|
||||||
return new PassportConfigurationEditor(playlistManager, userPreferences);
|
return new PassportConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case P25_PHASE1:
|
case P25_PHASE1:
|
||||||
return new P25P1ConfigurationEditor(playlistManager, userPreferences);
|
return new P25P1ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
case P25_PHASE2:
|
case P25_PHASE2:
|
||||||
return new P25P2ConfigurationEditor(playlistManager, userPreferences);
|
return new P25P2ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||||
default:
|
default:
|
||||||
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -28,6 +25,7 @@ import io.github.dsheirer.module.decode.DecoderFactory;
|
|||||||
import io.github.dsheirer.module.decode.DecoderType;
|
import io.github.dsheirer.module.decode.DecoderType;
|
||||||
import io.github.dsheirer.playlist.PlaylistManager;
|
import io.github.dsheirer.playlist.PlaylistManager;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
@@ -79,6 +77,7 @@ public class ChannelEditor extends SplitPane
|
|||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
||||||
private PlaylistManager mPlaylistManager;
|
private PlaylistManager mPlaylistManager;
|
||||||
|
private TunerManager mTunerManager;
|
||||||
private UserPreferences mUserPreferences;
|
private UserPreferences mUserPreferences;
|
||||||
private TableView<Channel> mChannelTableView;
|
private TableView<Channel> mChannelTableView;
|
||||||
private Label mPlaceholderLabel;
|
private Label mPlaceholderLabel;
|
||||||
@@ -102,11 +101,12 @@ public class ChannelEditor extends SplitPane
|
|||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager containing playlists and channel configurations
|
* @param playlistManager containing playlists and channel configurations
|
||||||
*/
|
*/
|
||||||
public ChannelEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public ChannelEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mPlaylistManager = playlistManager;
|
mPlaylistManager = playlistManager;
|
||||||
|
mTunerManager = tunerManager;
|
||||||
mUserPreferences = userPreferences;
|
mUserPreferences = userPreferences;
|
||||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, userPreferences);
|
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, mTunerManager, userPreferences);
|
||||||
|
|
||||||
HBox channelsBox = new HBox();
|
HBox channelsBox = new HBox();
|
||||||
channelsBox.setSpacing(10.0);
|
channelsBox.setSpacing(10.0);
|
||||||
@@ -203,7 +203,7 @@ public class ChannelEditor extends SplitPane
|
|||||||
if(editor == null)
|
if(editor == null)
|
||||||
{
|
{
|
||||||
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager,
|
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager,
|
||||||
mUserPreferences);
|
mTunerManager, mUserPreferences);
|
||||||
|
|
||||||
if(editor != null)
|
if(editor != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -40,6 +37,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
@@ -96,11 +94,14 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public DMRConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public DMRConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
@@ -240,7 +241,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@@ -74,12 +72,14 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
* @param userPreferences
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public LTRConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public LTRConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
@@ -210,7 +210,7 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@@ -74,12 +72,13 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
* @param userPreferences
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public LTRNetConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public LTRNetConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
@@ -210,7 +209,7 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -40,6 +37,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
@@ -84,12 +82,14 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
* @param userPreferences
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public MPT1327ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public MPT1327ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
@@ -195,7 +195,7 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -42,6 +39,7 @@ import io.github.dsheirer.protocol.Protocol;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
@@ -92,12 +90,14 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
* @param userPreferences
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public NBFMConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public NBFMConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
@@ -228,7 +228,7 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -38,6 +35,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
@@ -80,12 +78,14 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param playlistManager
|
* @param playlistManager for playlists
|
||||||
* @param userPreferences
|
* @param tunerManager for tuners
|
||||||
|
* @param userPreferences for preferences
|
||||||
*/
|
*/
|
||||||
public P25P1ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public P25P1ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
@@ -191,7 +191,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
@@ -73,9 +71,10 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
* @param userPreferences
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public P25P2ConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public P25P2ConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||||
@@ -179,7 +178,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -38,6 +35,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
|||||||
import io.github.dsheirer.record.RecorderType;
|
import io.github.dsheirer.record.RecorderType;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.TitledPane;
|
import javafx.scene.control.TitledPane;
|
||||||
@@ -69,9 +67,10 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
* @param playlistManager
|
* @param playlistManager
|
||||||
* @param userPreferences
|
* @param userPreferences
|
||||||
*/
|
*/
|
||||||
public PassportConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public PassportConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getSourcePane());
|
getTitledPanesBox().getChildren().add(getSourcePane());
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||||
@@ -155,7 +154,7 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
{
|
{
|
||||||
if(mSourceConfigurationEditor == null)
|
if(mSourceConfigurationEditor == null)
|
||||||
{
|
{
|
||||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel());
|
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager);
|
||||||
|
|
||||||
//Add a listener so that we can push change notifications up to this editor
|
//Add a listener so that we can push change notifications up to this editor
|
||||||
mSourceConfigurationEditor.modifiedProperty()
|
mSourceConfigurationEditor.modifiedProperty()
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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;
|
package io.github.dsheirer.gui.playlist.channel;
|
||||||
@@ -30,6 +27,7 @@ import io.github.dsheirer.playlist.PlaylistManager;
|
|||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.scene.control.TitledPane;
|
import javafx.scene.control.TitledPane;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -46,9 +44,10 @@ public class UnknownConfigurationEditor extends ChannelConfigurationEditor
|
|||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
* @param aliasModel
|
* @param aliasModel
|
||||||
*/
|
*/
|
||||||
public UnknownConfigurationEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
public UnknownConfigurationEditor(PlaylistManager playlistManager, TunerManager tunerManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
super(playlistManager, userPreferences);
|
super(playlistManager, tunerManager, userPreferences);
|
||||||
getTitledPanesBox().getChildren().add(getDecoderPane());
|
getTitledPanesBox().getChildren().add(getDecoderPane());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.source;
|
package io.github.dsheirer.gui.playlist.source;
|
||||||
@@ -25,8 +22,8 @@ package io.github.dsheirer.gui.playlist.source;
|
|||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
import io.github.dsheirer.source.tuner.TunerModel;
|
|
||||||
import io.github.dsheirer.source.tuner.channel.rotation.ChannelRotationMonitor;
|
import io.github.dsheirer.source.tuner.channel.rotation.ChannelRotationMonitor;
|
||||||
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.beans.value.ObservableValue;
|
import javafx.beans.value.ObservableValue;
|
||||||
@@ -59,7 +56,7 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
|||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(FrequencyEditor.class);
|
private final static Logger mLog = LoggerFactory.getLogger(FrequencyEditor.class);
|
||||||
private static final String NONE = "(none) ";
|
private static final String NONE = "(none) ";
|
||||||
private TunerModel mTunerModel;
|
private TunerManager mTunerManager;
|
||||||
private FrequencyBox mPrimaryFrequencyBox;
|
private FrequencyBox mPrimaryFrequencyBox;
|
||||||
private ObservableList<FrequencyBox> mFrequencyBoxes = FXCollections.observableArrayList();
|
private ObservableList<FrequencyBox> mFrequencyBoxes = FXCollections.observableArrayList();
|
||||||
private ComboBox<String> mPreferredTunerComboBox;
|
private ComboBox<String> mPreferredTunerComboBox;
|
||||||
@@ -75,13 +72,13 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
|||||||
* define constraints for the channel rotation delay monitor, how long the monitor dwells on each frequency in a
|
* define constraints for the channel rotation delay monitor, how long the monitor dwells on each frequency in a
|
||||||
* multi-frequency configuration.
|
* multi-frequency configuration.
|
||||||
*
|
*
|
||||||
* @param tunerModel for accessing list of tuners to select a preferred tuner
|
* @param tunerManager for accessing list of tuners to select a preferred tuner
|
||||||
* @param minRotationDelay in milliseconds for channel/frequency dwell
|
* @param minRotationDelay in milliseconds for channel/frequency dwell
|
||||||
* @param maxRotationDelay in milliseconds for channel/frequency dwell
|
* @param maxRotationDelay in milliseconds for channel/frequency dwell
|
||||||
*/
|
*/
|
||||||
public FrequencyEditor(TunerModel tunerModel, int minRotationDelay, int maxRotationDelay, int defaultRotationDelay)
|
public FrequencyEditor(TunerManager tunerManager, int minRotationDelay, int maxRotationDelay, int defaultRotationDelay)
|
||||||
{
|
{
|
||||||
mTunerModel = tunerModel;
|
mTunerManager = tunerManager;
|
||||||
mAllowMultipleFrequencies = true;
|
mAllowMultipleFrequencies = true;
|
||||||
mFrequencyRotationMinimum = minRotationDelay;
|
mFrequencyRotationMinimum = minRotationDelay;
|
||||||
mFrequencyRotationMaximum = maxRotationDelay;
|
mFrequencyRotationMaximum = maxRotationDelay;
|
||||||
@@ -91,11 +88,11 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance with a default behavior of single frequency support only.
|
* Constructs an instance with a default behavior of single frequency support only.
|
||||||
* @param tunerModel for accessing list of tuners to select a preferred tuner
|
* @param tunerManager for accessing list of tuners to select a preferred tuner
|
||||||
*/
|
*/
|
||||||
public FrequencyEditor(TunerModel tunerModel)
|
public FrequencyEditor(TunerManager tunerManager)
|
||||||
{
|
{
|
||||||
mTunerModel = tunerModel;
|
mTunerManager = tunerManager;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,9 +330,9 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
|||||||
getPreferredTunerComboBox().getItems().clear();
|
getPreferredTunerComboBox().getItems().clear();
|
||||||
getPreferredTunerComboBox().getItems().add(NONE);
|
getPreferredTunerComboBox().getItems().add(NONE);
|
||||||
|
|
||||||
if(mTunerModel != null)
|
if(mTunerManager != null)
|
||||||
{
|
{
|
||||||
getPreferredTunerComboBox().getItems().addAll(mTunerModel.getTunerNames());
|
getPreferredTunerComboBox().getItems().addAll(mTunerManager.getPreferredTunerNames());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import javafx.scene.control.TextField;
|
|||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.controlsfx.control.ToggleSwitch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcastify calls API configuration editor
|
* Broadcastify calls API configuration editor
|
||||||
@@ -47,6 +48,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
private TextField mApiKeyTextField;
|
private TextField mApiKeyTextField;
|
||||||
private TextField mHostTextField;
|
private TextField mHostTextField;
|
||||||
private GridPane mEditorPane;
|
private GridPane mEditorPane;
|
||||||
|
private ToggleSwitch mTestEnabledToggleSwitch;
|
||||||
|
private IntegerTextField mTestIntervalTextField;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance
|
* Constructs an instance
|
||||||
@@ -66,6 +69,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
getApiKeyTextField().setDisable(item == null);
|
getApiKeyTextField().setDisable(item == null);
|
||||||
getHostTextField().setDisable(item == null);
|
getHostTextField().setDisable(item == null);
|
||||||
getMaxAgeTextField().setDisable(item == null);
|
getMaxAgeTextField().setDisable(item == null);
|
||||||
|
getTestEnabledToggleSwitch().setDisable(item == null);
|
||||||
|
getTestIntervalTextField().setDisable(item == null);
|
||||||
|
|
||||||
if(item != null)
|
if(item != null)
|
||||||
{
|
{
|
||||||
@@ -73,6 +78,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
getApiKeyTextField().setText(item.getApiKey());
|
getApiKeyTextField().setText(item.getApiKey());
|
||||||
getHostTextField().setText(item.getHost());
|
getHostTextField().setText(item.getHost());
|
||||||
getMaxAgeTextField().set((int)(item.getMaximumRecordingAge() / 1000));
|
getMaxAgeTextField().set((int)(item.getMaximumRecordingAge() / 1000));
|
||||||
|
getTestEnabledToggleSwitch().setSelected(item.isTestEnabled());
|
||||||
|
getTestIntervalTextField().set(item.getTestInterval());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -80,6 +87,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
getApiKeyTextField().setText(null);
|
getApiKeyTextField().setText(null);
|
||||||
getHostTextField().setText(null);
|
getHostTextField().setText(null);
|
||||||
getMaxAgeTextField().set(0);
|
getMaxAgeTextField().set(0);
|
||||||
|
getTestEnabledToggleSwitch().setSelected(false);
|
||||||
|
getTestIntervalTextField().set(15);
|
||||||
}
|
}
|
||||||
|
|
||||||
modifiedProperty().set(false);
|
modifiedProperty().set(false);
|
||||||
@@ -100,6 +109,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
getItem().setHost(getHostTextField().getText());
|
getItem().setHost(getHostTextField().getText());
|
||||||
getItem().setApiKey(getApiKeyTextField().getText());
|
getItem().setApiKey(getApiKeyTextField().getText());
|
||||||
getItem().setMaximumRecordingAge(getMaxAgeTextField().get() * 1000);
|
getItem().setMaximumRecordingAge(getMaxAgeTextField().get() * 1000);
|
||||||
|
getItem().setTestEnabled(getTestEnabledToggleSwitch().isSelected());
|
||||||
|
getItem().setTestInterval(getTestIntervalTextField().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
super.save();
|
super.save();
|
||||||
@@ -177,6 +188,22 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
GridPane.setConstraints(getMaxAgeTextField(), 1, row);
|
GridPane.setConstraints(getMaxAgeTextField(), 1, row);
|
||||||
mEditorPane.getChildren().add(getMaxAgeTextField());
|
mEditorPane.getChildren().add(getMaxAgeTextField());
|
||||||
|
|
||||||
|
Label testEnabledLabel = new Label("Send Periodic Keep-Alive");
|
||||||
|
GridPane.setHalignment(testEnabledLabel, HPos.RIGHT);
|
||||||
|
GridPane.setConstraints(testEnabledLabel, 0, ++row);
|
||||||
|
mEditorPane.getChildren().add(testEnabledLabel);
|
||||||
|
|
||||||
|
GridPane.setConstraints(getTestEnabledToggleSwitch(), 1, row);
|
||||||
|
mEditorPane.getChildren().add(getTestEnabledToggleSwitch());
|
||||||
|
|
||||||
|
Label testIntervalLabel = new Label("Ping Interval (minutes)");
|
||||||
|
GridPane.setHalignment(testIntervalLabel, HPos.RIGHT);
|
||||||
|
GridPane.setConstraints(testIntervalLabel, 3, row);
|
||||||
|
mEditorPane.getChildren().add(testIntervalLabel);
|
||||||
|
|
||||||
|
GridPane.setConstraints(getTestIntervalTextField(), 4, row);
|
||||||
|
mEditorPane.getChildren().add(getTestIntervalTextField());
|
||||||
|
|
||||||
GridPane.setConstraints(getTestButton(), 1, ++row);
|
GridPane.setConstraints(getTestButton(), 1, ++row);
|
||||||
mEditorPane.getChildren().add(getTestButton());
|
mEditorPane.getChildren().add(getTestButton());
|
||||||
}
|
}
|
||||||
@@ -232,6 +259,31 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
|||||||
return mSystemIdTextField;
|
return mSystemIdTextField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ToggleSwitch getTestEnabledToggleSwitch()
|
||||||
|
{
|
||||||
|
if(mTestEnabledToggleSwitch == null)
|
||||||
|
{
|
||||||
|
mTestEnabledToggleSwitch = new ToggleSwitch();
|
||||||
|
mTestEnabledToggleSwitch.setDisable(true);
|
||||||
|
mTestEnabledToggleSwitch.selectedProperty()
|
||||||
|
.addListener((observable, oldValue, newValue) -> modifiedProperty().set(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return mTestEnabledToggleSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntegerTextField getTestIntervalTextField()
|
||||||
|
{
|
||||||
|
if(mTestIntervalTextField == null)
|
||||||
|
{
|
||||||
|
mTestIntervalTextField = new IntegerTextField();
|
||||||
|
mTestIntervalTextField.setDisable(true);
|
||||||
|
mTestIntervalTextField.textProperty().addListener(mEditorModificationListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mTestIntervalTextField;
|
||||||
|
}
|
||||||
|
|
||||||
private Button getTestButton()
|
private Button getTestButton()
|
||||||
{
|
{
|
||||||
if(mTestButton == null)
|
if(mTestButton == null)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import javafx.geometry.Insets;
|
|||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
|
import org.controlsfx.control.ToggleSwitch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Icecast streaming configuration editor
|
* Icecast streaming configuration editor
|
||||||
@@ -37,6 +38,7 @@ import javafx.scene.layout.GridPane;
|
|||||||
public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastConfiguration>
|
public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastConfiguration>
|
||||||
{
|
{
|
||||||
private GridPane mEditorPane;
|
private GridPane mEditorPane;
|
||||||
|
private ToggleSwitch mInlineToggleSwitch;
|
||||||
private TextField mMountPointTextField;
|
private TextField mMountPointTextField;
|
||||||
private TextField mUserNameTextField;
|
private TextField mUserNameTextField;
|
||||||
private TextField mDescriptionTextField;
|
private TextField mDescriptionTextField;
|
||||||
@@ -52,6 +54,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
public void setItem(IcecastConfiguration item)
|
public void setItem(IcecastConfiguration item)
|
||||||
{
|
{
|
||||||
getMountPointTextField().setDisable(item == null);
|
getMountPointTextField().setDisable(item == null);
|
||||||
|
getInlineToggleSwitch().setDisable(item == null);
|
||||||
getUserNameTextField().setDisable(item == null);
|
getUserNameTextField().setDisable(item == null);
|
||||||
getDescriptionTextField().setDisable(item == null);
|
getDescriptionTextField().setDisable(item == null);
|
||||||
getGenreTextField().setDisable(item == null);
|
getGenreTextField().setDisable(item == null);
|
||||||
@@ -60,6 +63,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
if(item != null)
|
if(item != null)
|
||||||
{
|
{
|
||||||
getMountPointTextField().setText(item.getMountPoint());
|
getMountPointTextField().setText(item.getMountPoint());
|
||||||
|
getInlineToggleSwitch().setSelected(item.getInline());
|
||||||
getUserNameTextField().setText(item.getUserName());
|
getUserNameTextField().setText(item.getUserName());
|
||||||
getDescriptionTextField().setText(item.getDescription());
|
getDescriptionTextField().setText(item.getDescription());
|
||||||
getGenreTextField().setText(item.getGenre());
|
getGenreTextField().setText(item.getGenre());
|
||||||
@@ -68,6 +72,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
getMountPointTextField().setText(null);
|
getMountPointTextField().setText(null);
|
||||||
|
getInlineToggleSwitch().setSelected(false);
|
||||||
getUserNameTextField().setText(null);
|
getUserNameTextField().setText(null);
|
||||||
getDescriptionTextField().setText(null);
|
getDescriptionTextField().setText(null);
|
||||||
getGenreTextField().setText(null);
|
getGenreTextField().setText(null);
|
||||||
@@ -83,6 +88,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
if(getItem() != null)
|
if(getItem() != null)
|
||||||
{
|
{
|
||||||
getItem().setMountPoint(getMountPointTextField().getText());
|
getItem().setMountPoint(getMountPointTextField().getText());
|
||||||
|
getItem().setInline(getInlineToggleSwitch().isSelected());
|
||||||
getItem().setUserName(getUserNameTextField().getText());
|
getItem().setUserName(getUserNameTextField().getText());
|
||||||
getItem().setDescription(getDescriptionTextField().getText());
|
getItem().setDescription(getDescriptionTextField().getText());
|
||||||
getItem().setGenre(getGenreTextField().getText());
|
getItem().setGenre(getGenreTextField().getText());
|
||||||
@@ -150,6 +156,14 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
GridPane.setConstraints(getMountPointTextField(), 1, 3);
|
GridPane.setConstraints(getMountPointTextField(), 1, 3);
|
||||||
mEditorPane.getChildren().add(getMountPointTextField());
|
mEditorPane.getChildren().add(getMountPointTextField());
|
||||||
|
|
||||||
|
Label inlineLabel = new Label("Inline Metadata");
|
||||||
|
GridPane.setHalignment(inlineLabel, HPos.RIGHT);
|
||||||
|
GridPane.setConstraints(inlineLabel, 2, 3);
|
||||||
|
mEditorPane.getChildren().add(inlineLabel);
|
||||||
|
|
||||||
|
GridPane.setConstraints(getInlineToggleSwitch(), 3, 3);
|
||||||
|
mEditorPane.getChildren().add(getInlineToggleSwitch());
|
||||||
|
|
||||||
Label userNameLabel = new Label("User Name");
|
Label userNameLabel = new Label("User Name");
|
||||||
GridPane.setHalignment(userNameLabel, HPos.RIGHT);
|
GridPane.setHalignment(userNameLabel, HPos.RIGHT);
|
||||||
GridPane.setConstraints(userNameLabel, 0, 4);
|
GridPane.setConstraints(userNameLabel, 0, 4);
|
||||||
@@ -226,6 +240,19 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
|||||||
return mMountPointTextField;
|
return mMountPointTextField;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ToggleSwitch getInlineToggleSwitch()
|
||||||
|
{
|
||||||
|
if(mInlineToggleSwitch == null)
|
||||||
|
{
|
||||||
|
mInlineToggleSwitch = new ToggleSwitch();
|
||||||
|
mInlineToggleSwitch.setDisable(true);
|
||||||
|
mInlineToggleSwitch.selectedProperty()
|
||||||
|
.addListener((observable, oldValue, newValue) -> modifiedProperty().set(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return mInlineToggleSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
private TextField getUserNameTextField()
|
private TextField getUserNameTextField()
|
||||||
{
|
{
|
||||||
if(mUserNameTextField == null)
|
if(mUserNameTextField == null)
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.streaming;
|
package io.github.dsheirer.gui.playlist.streaming;
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
* it under the terms of the GNU General Public License as published by
|
||||||
* later version.
|
* 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
|
* This program is distributed in the hope that it will be useful,
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
* 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.
|
* You should have received a copy of the GNU General Public License
|
||||||
* If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
|
|
||||||
package io.github.dsheirer.gui.preference;
|
package io.github.dsheirer.gui.preference;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* *****************************************************************************
|
||||||
* sdrtrunk
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
* *****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.github.dsheirer.gui.preference.directory;
|
package io.github.dsheirer.gui.preference.directory;
|
||||||
@@ -63,6 +62,11 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
private Button mResetApplicationLogsButton;
|
private Button mResetApplicationLogsButton;
|
||||||
private Label mApplicationLogsPathLabel;
|
private Label mApplicationLogsPathLabel;
|
||||||
|
|
||||||
|
private Label mConfigurationLabel;
|
||||||
|
private Button mChangeConfigurationButton;
|
||||||
|
private Button mResetConfigurationButton;
|
||||||
|
private Label mConfigurationPathLabel;
|
||||||
|
|
||||||
private Label mEventLogsLabel;
|
private Label mEventLogsLabel;
|
||||||
private Button mChangeEventLogsButton;
|
private Button mChangeEventLogsButton;
|
||||||
private Button mResetEventLogsButton;
|
private Button mResetEventLogsButton;
|
||||||
@@ -154,6 +158,19 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
mEditorPane.add(getResetApplicationLogsButton(), 3, row++);
|
mEditorPane.add(getResetApplicationLogsButton(), 3, row++);
|
||||||
|
|
||||||
|
|
||||||
|
GridPane.setMargin(getConfigurationLabel(), new Insets(0, 10, 0, 0));
|
||||||
|
mEditorPane.add(getConfigurationLabel(), 0, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getConfigurationPathLabel(), new Insets(0, 10, 0, 0));
|
||||||
|
mEditorPane.add(getConfigurationPathLabel(), 1, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getChangeConfigurationButton(), new Insets(2, 10, 2, 0));
|
||||||
|
mEditorPane.add(getChangeConfigurationButton(), 2, row);
|
||||||
|
|
||||||
|
GridPane.setMargin(getResetConfigurationButton(), new Insets(2, 0, 2, 0));
|
||||||
|
mEditorPane.add(getResetConfigurationButton(), 3, row++);
|
||||||
|
|
||||||
|
|
||||||
GridPane.setMargin(getEventLogsLabel(), new Insets(0, 10, 0, 0));
|
GridPane.setMargin(getEventLogsLabel(), new Insets(0, 10, 0, 0));
|
||||||
mEditorPane.add(getEventLogsLabel(), 0, row);
|
mEditorPane.add(getEventLogsLabel(), 0, row);
|
||||||
|
|
||||||
@@ -365,6 +382,71 @@ public class DirectoryPreferenceEditor extends HBox
|
|||||||
return mApplicationLogsPathLabel;
|
return mApplicationLogsPathLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Label getConfigurationLabel()
|
||||||
|
{
|
||||||
|
if(mConfigurationLabel == null)
|
||||||
|
{
|
||||||
|
mConfigurationLabel = new Label("Configuration");
|
||||||
|
}
|
||||||
|
|
||||||
|
return mConfigurationLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getChangeConfigurationButton()
|
||||||
|
{
|
||||||
|
if(mChangeConfigurationButton == null)
|
||||||
|
{
|
||||||
|
mChangeConfigurationButton = new Button("Change...");
|
||||||
|
mChangeConfigurationButton.setOnAction(new EventHandler<ActionEvent>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event)
|
||||||
|
{
|
||||||
|
DirectoryChooser directoryChooser = new DirectoryChooser();
|
||||||
|
directoryChooser.setTitle("Select Configuration Folder");
|
||||||
|
directoryChooser.setInitialDirectory(mDirectoryPreference.getDirectoryConfiguration().toFile());
|
||||||
|
Stage stage = (Stage)getChangeConfigurationButton().getScene().getWindow();
|
||||||
|
File selected = directoryChooser.showDialog(stage);
|
||||||
|
|
||||||
|
if(selected != null)
|
||||||
|
{
|
||||||
|
mDirectoryPreference.setDirectoryConfiguration(selected.toPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mChangeConfigurationButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Button getResetConfigurationButton()
|
||||||
|
{
|
||||||
|
if(mResetConfigurationButton == null)
|
||||||
|
{
|
||||||
|
mResetConfigurationButton = new Button("Reset");
|
||||||
|
mResetConfigurationButton.setOnAction(new EventHandler<ActionEvent>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void handle(ActionEvent event)
|
||||||
|
{
|
||||||
|
mDirectoryPreference.resetDirectoryConfiguration();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mResetConfigurationButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Label getConfigurationPathLabel()
|
||||||
|
{
|
||||||
|
if(mConfigurationPathLabel == null)
|
||||||
|
{
|
||||||
|
mConfigurationPathLabel = new Label(mDirectoryPreference.getDirectoryConfiguration().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mConfigurationPathLabel;
|
||||||
|
}
|
||||||
|
|
||||||
private Label getEventLogsLabel()
|
private Label getEventLogsLabel()
|
||||||
{
|
{
|
||||||
if(mEventLogsLabel == null)
|
if(mEventLogsLabel == null)
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.identifier;
|
package io.github.dsheirer.identifier;
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
* it under the terms of the GNU General Public License as published by
|
||||||
* later version.
|
* 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
|
* This program is distributed in the hope that it will be useful,
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
* 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.
|
* You should have received a copy of the GNU General Public License
|
||||||
* If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.identifier;
|
package io.github.dsheirer.identifier;
|
||||||
|
|
||||||
import io.github.dsheirer.protocol.Protocol;
|
import io.github.dsheirer.protocol.Protocol;
|
||||||
|
|||||||
@@ -1,18 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
* it under the terms of the GNU General Public License as published by
|
||||||
* later version.
|
* 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
|
* This program is distributed in the hope that it will be useful,
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
* 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.
|
* You should have received a copy of the GNU General Public License
|
||||||
* If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* ****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.identifier;
|
package io.github.dsheirer.identifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -278,29 +278,43 @@ public class IdentifierCollection
|
|||||||
*/
|
*/
|
||||||
public Identifier getFromIdentifier()
|
public Identifier getFromIdentifier()
|
||||||
{
|
{
|
||||||
List<Identifier> fromIdentifiers = getIdentifiers(Role.FROM);
|
Identifier from = getIdentifier(IdentifierClass.USER, Form.RADIO, Role.FROM);
|
||||||
|
|
||||||
if(!fromIdentifiers.isEmpty())
|
if(from == null)
|
||||||
{
|
{
|
||||||
return fromIdentifiers.get(0);
|
List<Identifier> fromIdentifiers = getIdentifiers(Role.FROM);
|
||||||
|
|
||||||
|
if(!fromIdentifiers.isEmpty())
|
||||||
|
{
|
||||||
|
from = fromIdentifiers.get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first identifier in this collection that is assigned a FROM role
|
* Returns the first identifier in this collection that is assigned a TO role
|
||||||
*/
|
*/
|
||||||
public Identifier getToIdentifier()
|
public Identifier getToIdentifier()
|
||||||
{
|
{
|
||||||
List<Identifier> toIdentifiers = getIdentifiers(Role.TO);
|
Identifier to = getIdentifier(IdentifierClass.USER, Form.PATCH_GROUP, Role.TO);
|
||||||
|
|
||||||
if(!toIdentifiers.isEmpty())
|
if(to == null)
|
||||||
{
|
{
|
||||||
return toIdentifiers.get(0);
|
to = getIdentifier(IdentifierClass.USER, Form.TALKGROUP, Role.TO);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
if(to == null)
|
||||||
|
{
|
||||||
|
List<Identifier> toIdentifiers = getIdentifiers(Role.TO);
|
||||||
|
if(!toIdentifiers.isEmpty())
|
||||||
|
{
|
||||||
|
to = toIdentifiers.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* SDR Trunk
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* ****************************************************************************
|
||||||
|
*/
|
||||||
package io.github.dsheirer.module.decode;
|
package io.github.dsheirer.module.decode;
|
||||||
|
|
||||||
import io.github.dsheirer.message.IMessage;
|
import io.github.dsheirer.message.IMessage;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2021 Dennis Sheirer
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|||||||
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * 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 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.module.decode;
|
package io.github.dsheirer.module.decode;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user