mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-10 23:57:25 -05:00
Compare commits
34 Commits
v0.5.0-bet
...
v0.5.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f67f90e8b0 | ||
|
|
5751c70212 | ||
|
|
4e15c426a8 | ||
|
|
ceda189260 | ||
|
|
fce0ae33e7 | ||
|
|
fc5c6ef841 | ||
|
|
d0033578d5 | ||
|
|
670ec3a097 | ||
|
|
8bfb1d5470 | ||
|
|
46a916a945 | ||
|
|
459e77390a | ||
|
|
f4ab46b79d | ||
|
|
3c58e98788 | ||
|
|
36de81248c | ||
|
|
925353d515 | ||
|
|
7c32897321 | ||
|
|
cbeda19d27 | ||
|
|
8148ca48af | ||
|
|
adcb55ffbc | ||
|
|
1152b13220 | ||
|
|
166383e1ed | ||
|
|
0d5d1b20e3 | ||
|
|
77ea43f61a | ||
|
|
f988344222 | ||
|
|
60489e1fef | ||
|
|
ac8aa17a80 | ||
|
|
25a42126df | ||
|
|
1b90e0b50c | ||
|
|
7f5ad7eb20 | ||
|
|
0e6713b6e2 | ||
|
|
96d3996bec | ||
|
|
0fb148d31e | ||
|
|
cebca28b19 | ||
|
|
af8cc0255e |
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@@ -1,7 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="liberica-17.0.2-fx" project-jdk-type="JavaSDK">
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="liberica-18.0.1-fx" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
26
build.gradle
26
build.gradle
@@ -28,7 +28,7 @@ repositories {
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
version = '0.5.0-beta2'
|
||||
version = '0.5.0'
|
||||
sourceCompatibility = '17'
|
||||
|
||||
sourceSets {
|
||||
@@ -58,7 +58,7 @@ dependencies {
|
||||
//mavenCentral/jcenter imports
|
||||
implementation 'ch.qos.logback:logback-classic: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.github.jiconfont:jiconfont-font_awesome:4.7.0.1'
|
||||
implementation 'com.github.jiconfont:jiconfont-javafx:1.0.0'
|
||||
@@ -86,7 +86,7 @@ dependencies {
|
||||
implementation 'org.usb4java:libusb4java:1.3.0'
|
||||
implementation 'org.usb4java:usb4java:1.3.0'
|
||||
implementation 'org.usb4java:usb4java-javax:1.3.0'
|
||||
implementation 'io.github.dsheirer:libusb4java-darwin-aarch64:1.3.0' //usb4java native lib for OSX M1 cpu
|
||||
implementation 'io.github.dsheirer:libusb4java-darwin-aarch64:1.3.1' //usb4java native lib for OSX M1 cpu
|
||||
implementation 'pl.edu.icm:JLargeArrays:1.6'
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
String jdk_base = '/home/denny/java_jdks/'
|
||||
String jdk_linux_aarch64 = jdk_base + 'linux-arm64/jdk-17.0.2-full'
|
||||
String jdk_linux_x86_64 = jdk_base + 'linux-x64/jdk-17.0.2-full'
|
||||
String jdk_osx_x86_64 = jdk_base + 'osx-x64/jdk-17.0.2-full.jdk'
|
||||
String jdk_osx_aarch64 = jdk_base + 'osx-arm64/jdk-17.0.2-full.jdk'
|
||||
String jdk_windows_x86_64 = jdk_base + 'windows-x64/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-18.0.1-full'
|
||||
String jdk_osx_x86_64 = jdk_base + 'osx-x64/jdk-18.0.1-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-18.0.1-full'
|
||||
|
||||
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()
|
||||
@@ -172,19 +172,19 @@ runtime {
|
||||
println("Building all runtime images")
|
||||
println("The [ > jre: ] build phase downloads several target JDKs and this may take a while ... please wait")
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.alias;
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.alias;
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.alias;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public class AudioSegmentBroadcaster<T extends AudioSegment> extends Broadcaster
|
||||
@Override
|
||||
public void broadcast(T audioSegment)
|
||||
{
|
||||
for(Listener<T> listener : mListeners)
|
||||
for(Listener<T> listener : getListeners())
|
||||
{
|
||||
audioSegment.incrementConsumerCount();
|
||||
listener.receive(audioSegment);
|
||||
|
||||
@@ -24,7 +24,10 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.Float;
|
||||
import java.lang.Math;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AudioUtils
|
||||
@@ -78,4 +81,43 @@ public class AudioUtils
|
||||
|
||||
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);
|
||||
|
||||
public static final int PROCESSOR_RUN_INTERVAL_MS = 1000;
|
||||
private ScheduledFuture mRecordingQueueProcessorFuture;
|
||||
private ScheduledFuture<?> mRecordingQueueProcessorFuture;
|
||||
|
||||
private RecordingQueueProcessor mRecordingQueueProcessor = new RecordingQueueProcessor();
|
||||
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
||||
@@ -52,6 +52,10 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
private long mMaximumRecordingAge;
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
protected abstract void broadcastAudio(byte[] audio);
|
||||
protected abstract void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection);
|
||||
|
||||
/**
|
||||
* Protocol-specific metadata updater
|
||||
@@ -205,13 +209,15 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
|
||||
super.setBroadcastState(state);
|
||||
|
||||
if(mBroadcastState.get() instanceof BroadcastState && ((BroadcastState)mBroadcastState.get()).isErrorState())
|
||||
if(mBroadcastState.get() != null && mBroadcastState.get().isErrorState())
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
if(!connected())
|
||||
{
|
||||
//Reset inline metadata
|
||||
mInlineRemaining = -1;
|
||||
//Remove all pending audio recordings
|
||||
while(!mAudioRecordingQueue.isEmpty())
|
||||
{
|
||||
@@ -265,9 +271,9 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
{
|
||||
private AtomicBoolean mProcessing = new AtomicBoolean();
|
||||
private ByteArrayInputStream mInputStream;
|
||||
private IdentifierCollection mInputIdentifierCollection;
|
||||
private long mFinalSilencePadding = 0;
|
||||
private int mBytesStreamedActual = 0;
|
||||
private int mBytesStreamedRequired = 0;
|
||||
private int mBytesToStreamPerInterval = 0;
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
@@ -278,51 +284,44 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
{
|
||||
if(mInputStream == null || mInputStream.available() <= 0)
|
||||
{
|
||||
if(mFinalSilencePadding > 0)
|
||||
{
|
||||
List<byte[]> finalSilence = mSilenceGenerator.generate(mFinalSilencePadding);
|
||||
|
||||
for(byte[] silence: finalSilence)
|
||||
{
|
||||
broadcastAudio(silence);
|
||||
}
|
||||
|
||||
mFinalSilencePadding = 0;
|
||||
}
|
||||
|
||||
nextRecording();
|
||||
}
|
||||
|
||||
if(mInputStream != null)
|
||||
{
|
||||
//We need to stream at 13.888 fps (144 byte frame) to achieve 2000 Bps or 16 kbps
|
||||
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());
|
||||
int length = FastMath.min(mBytesToStreamPerInterval, mInputStream.available());
|
||||
|
||||
byte[] audio = new byte[length];
|
||||
|
||||
try
|
||||
{
|
||||
mBytesStreamedActual += mInputStream.read(audio);
|
||||
|
||||
broadcastAudio(audio);
|
||||
int read = mInputStream.read(audio);
|
||||
broadcastAudio(audio, mInputIdentifierCollection);
|
||||
}
|
||||
catch(IOException 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
|
||||
{
|
||||
List<byte[]> silenceFrames = mSilenceGenerator.generate(PROCESSOR_RUN_INTERVAL_MS);
|
||||
for(byte[] silence: silenceFrames)
|
||||
{
|
||||
broadcastAudio(silence);
|
||||
broadcastAudio(silence, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -340,9 +339,6 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
*/
|
||||
private void nextRecording()
|
||||
{
|
||||
mBytesStreamedActual = 0;
|
||||
mBytesStreamedRequired = 0;
|
||||
|
||||
boolean metadataUpdateRequired = false;
|
||||
|
||||
if(mInputStream != null)
|
||||
@@ -354,6 +350,7 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
}
|
||||
|
||||
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
|
||||
//age limits and/or delay elapsed
|
||||
@@ -381,9 +378,14 @@ public abstract class AudioStreamingBroadcaster<T extends BroadcastConfiguration
|
||||
{
|
||||
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);
|
||||
mInputIdentifierCollection = nextRecording.getIdentifierCollection();
|
||||
|
||||
mFinalSilencePadding = 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);
|
||||
|
||||
mInputStream = null;
|
||||
mInputIdentifierCollection = null;
|
||||
metadataUpdateRequired = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.audio.broadcast;
|
||||
|
||||
|
||||
@@ -30,10 +30,8 @@ import io.github.dsheirer.audio.broadcast.shoutcast.v1.ShoutcastV1AudioBroadcast
|
||||
import io.github.dsheirer.audio.broadcast.shoutcast.v1.ShoutcastV1Configuration;
|
||||
import io.github.dsheirer.audio.broadcast.shoutcast.v2.ShoutcastV2AudioStreamingBroadcaster;
|
||||
import io.github.dsheirer.audio.broadcast.shoutcast.v2.ShoutcastV2Configuration;
|
||||
import io.github.dsheirer.audio.convert.IAudioConverter;
|
||||
import io.github.dsheirer.audio.convert.ISilenceGenerator;
|
||||
import io.github.dsheirer.audio.convert.InputAudioFormat;
|
||||
import io.github.dsheirer.audio.convert.MP3AudioConverter;
|
||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||
import io.github.dsheirer.audio.convert.MP3SilenceGenerator;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
@@ -88,26 +86,6 @@ public class BroadcastFactory
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an audio convert to convert from 8 kHz PCM audio to the specified format
|
||||
*
|
||||
* @param configuration containing the requested output audio format
|
||||
* @return audio convert or null
|
||||
*/
|
||||
public static IAudioConverter getAudioConverter(BroadcastConfiguration configuration, InputAudioFormat inputAudioFormat,
|
||||
MP3Setting mp3Setting)
|
||||
{
|
||||
switch(configuration.getBroadcastFormat())
|
||||
{
|
||||
case MP3:
|
||||
return new MP3AudioConverter(inputAudioFormat, mp3Setting);
|
||||
default:
|
||||
mLog.info("Unrecognized broadcastAudio format: " + configuration.getBroadcastFormat().name());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a broadcastAudio configuration for the specified server type and format
|
||||
*
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.audio.broadcast;
|
||||
|
||||
@@ -68,6 +68,7 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
||||
private static final String MULTIPART_TYPE = "multipart";
|
||||
private static final String DEFAULT_SUBTYPE = "form-data";
|
||||
private static final String MULTIPART_FORM_DATA = MULTIPART_TYPE + "/" + DEFAULT_SUBTYPE;
|
||||
private ScheduledFuture<?> mBroadcastifyTestFuture;
|
||||
private Queue<AudioRecording> mAudioRecordingQueue = new LinkedTransferQueue<>();
|
||||
private ScheduledFuture<?> mAudioRecordingProcessorFuture;
|
||||
private HttpClient mHttpClient = HttpClient.newBuilder()
|
||||
@@ -109,6 +110,12 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
||||
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)
|
||||
{
|
||||
mAudioRecordingProcessorFuture = ThreadPool.SCHEDULED.scheduleAtFixedRate(new AudioRecordingProcessor(),
|
||||
@@ -122,6 +129,11 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
||||
@Override
|
||||
public void stop()
|
||||
{
|
||||
if(mBroadcastifyTestFuture != null)
|
||||
{
|
||||
mBroadcastifyTestFuture.cancel(true);
|
||||
mBroadcastifyTestFuture = null;
|
||||
}
|
||||
if(mAudioRecordingProcessorFuture != null)
|
||||
{
|
||||
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
|
||||
*/
|
||||
@@ -418,28 +447,20 @@ public class BroadcastifyCallBroadcaster extends AbstractAudioBroadcaster<Broadc
|
||||
*/
|
||||
private static String getTo(AudioRecording audioRecording)
|
||||
{
|
||||
List<Identifier> toIdentifiers = audioRecording.getIdentifierCollection().getIdentifiers(Role.TO);
|
||||
Identifier identifier = audioRecording.getIdentifierCollection().getToIdentifier();
|
||||
|
||||
//Format a patch group first, if there are multiples
|
||||
for(Identifier identifier: toIdentifiers)
|
||||
if(identifier instanceof PatchGroupIdentifier patchGroupIdentifier)
|
||||
{
|
||||
if(identifier instanceof PatchGroupIdentifier patchGroupIdentifier)
|
||||
{
|
||||
return format(patchGroupIdentifier);
|
||||
}
|
||||
return format(patchGroupIdentifier);
|
||||
}
|
||||
|
||||
for(Identifier identifier: toIdentifiers)
|
||||
else if(identifier instanceof TalkgroupIdentifier talkgroupIdentifier)
|
||||
{
|
||||
if(identifier instanceof TalkgroupIdentifier talkgroupIdentifier)
|
||||
{
|
||||
return String.valueOf(RadioReferenceDecoder.convertToRadioReferenceTalkgroup(talkgroupIdentifier.getValue(),
|
||||
talkgroupIdentifier.getProtocol()));
|
||||
}
|
||||
else if(identifier instanceof RadioIdentifier radioIdentifier)
|
||||
{
|
||||
return radioIdentifier.getValue().toString();
|
||||
}
|
||||
return String.valueOf(RadioReferenceDecoder.convertToRadioReferenceTalkgroup(talkgroupIdentifier.getValue(),
|
||||
talkgroupIdentifier.getProtocol()));
|
||||
}
|
||||
else if(identifier instanceof RadioIdentifier radioIdentifier)
|
||||
{
|
||||
return radioIdentifier.getValue().toString();
|
||||
}
|
||||
|
||||
return "0";
|
||||
|
||||
@@ -24,7 +24,9 @@ import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
|
||||
import io.github.dsheirer.audio.broadcast.BroadcastFormat;
|
||||
import io.github.dsheirer.audio.broadcast.BroadcastServerType;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
@@ -42,6 +44,8 @@ public class BroadcastifyCallConfiguration extends BroadcastConfiguration
|
||||
|
||||
private IntegerProperty mSystemID = new SimpleIntegerProperty();
|
||||
private StringProperty mApiKey = new SimpleStringProperty();
|
||||
private BooleanProperty mTestEnabled= new SimpleBooleanProperty(false);
|
||||
private IntegerProperty mTestInterval = new SimpleIntegerProperty(15);
|
||||
|
||||
/**
|
||||
* Constructor for faster jackson
|
||||
@@ -128,6 +132,34 @@ public class BroadcastifyCallConfiguration extends BroadcastConfiguration
|
||||
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
|
||||
public BroadcastConfiguration copyOf()
|
||||
{
|
||||
|
||||
@@ -54,6 +54,7 @@ public class BroadcastifyFeedConfiguration extends IcecastTCPConfiguration
|
||||
setBitRate(16);
|
||||
setChannels(1);
|
||||
setSampleRate(8000);
|
||||
setInline(true);
|
||||
}
|
||||
|
||||
public static BroadcastifyFeedConfiguration from(UserFeedBroadcast userFeedBroadcast)
|
||||
@@ -86,9 +87,9 @@ public class BroadcastifyFeedConfiguration extends IcecastTCPConfiguration
|
||||
copy.setName(getName());
|
||||
copy.setHost(getHost());
|
||||
copy.setPort(getPort());
|
||||
copy.setInline(getInline());
|
||||
copy.setPassword(getPassword());
|
||||
copy.setDelay(getDelay());
|
||||
|
||||
copy.setEnabled(false);
|
||||
|
||||
//Icecast Configuration Parameters
|
||||
|
||||
@@ -28,7 +28,7 @@ import io.github.dsheirer.audio.convert.MP3Setting;
|
||||
public abstract class IcecastAudioBroadcaster extends AudioStreamingBroadcaster
|
||||
{
|
||||
private IBroadcastMetadataUpdater mMetadataUpdater;
|
||||
private AliasModel mAliasModel;
|
||||
protected AliasModel mAliasModel;
|
||||
|
||||
public IcecastAudioBroadcaster(BroadcastConfiguration broadcastConfiguration, InputAudioFormat inputAudioFormat,
|
||||
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.AliasModel;
|
||||
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.Identifier;
|
||||
import io.github.dsheirer.identifier.IdentifierClass;
|
||||
@@ -73,6 +75,12 @@ public class IcecastBroadcastMetadataUpdater implements IBroadcastMetadataUpdate
|
||||
*/
|
||||
public void update(IdentifierCollection identifierCollection)
|
||||
{
|
||||
if(mIcecastConfiguration.hasInline())
|
||||
{
|
||||
// Never send out-of-band metadata if inline metadata is enabled.
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
try
|
||||
@@ -84,7 +92,7 @@ public class IcecastBroadcastMetadataUpdater implements IBroadcastMetadataUpdate
|
||||
sb.append("/admin/metadata?mode=updinfo&mount=");
|
||||
sb.append(URLEncoder.encode(mIcecastConfiguration.getMountPoint(), UTF8));
|
||||
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)
|
||||
{
|
||||
@@ -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 mSampleRate = 8000;
|
||||
private String mURL;
|
||||
private boolean mInline = true;
|
||||
|
||||
public IcecastConfiguration(BroadcastFormat format)
|
||||
{
|
||||
@@ -275,6 +276,37 @@ public abstract class IcecastConfiguration extends BroadcastConfiguration
|
||||
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
|
||||
public boolean isValid()
|
||||
{
|
||||
|
||||
@@ -20,9 +20,11 @@ package io.github.dsheirer.audio.broadcast.icecast;
|
||||
|
||||
import io.github.dsheirer.alias.AliasModel;
|
||||
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.MP3AudioConverter;
|
||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||
import io.github.dsheirer.properties.SystemProperties;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.apache.mina.core.RuntimeIoException;
|
||||
@@ -42,6 +44,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.net.ConnectException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -80,14 +83,41 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
||||
* Broadcasts the audio frame or sequence
|
||||
*/
|
||||
@Override
|
||||
protected void broadcastAudio(byte[] audio)
|
||||
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||
{
|
||||
if(audio != null && audio.length > 0 && connect() && mStreamingSession != null && mStreamingSession.isConnected())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -238,6 +268,17 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -55,6 +55,7 @@ public class IcecastHTTPConfiguration extends IcecastConfiguration
|
||||
copy.setName(getName());
|
||||
copy.setHost(getHost());
|
||||
copy.setPort(getPort());
|
||||
copy.setInline(getInline());
|
||||
copy.setPassword(getPassword());
|
||||
copy.setDelay(getDelay());
|
||||
copy.setEnabled(false);
|
||||
|
||||
@@ -33,6 +33,7 @@ public enum IcecastHeader
|
||||
PUBLIC("ice-public"),
|
||||
URL("ice-url"),
|
||||
USER_AGENT("User-Agent"),
|
||||
METAINT("icy-metaint"),
|
||||
|
||||
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.audio.broadcast.BroadcastState;
|
||||
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.MP3AudioConverter;
|
||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||
import io.github.dsheirer.properties.SystemProperties;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.apache.mina.core.RuntimeIoException;
|
||||
@@ -39,13 +41,14 @@ import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.channels.UnresolvedAddressException;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class IcecastTCPAudioBroadcaster extends IcecastAudioBroadcaster
|
||||
{
|
||||
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 static final long RECONNECT_INTERVAL_MILLISECONDS = 3000; //3 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
|
||||
*/
|
||||
@Override
|
||||
protected void broadcastAudio(byte[] audio)
|
||||
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ public class IcecastTCPConfiguration extends IcecastConfiguration
|
||||
copy.setName(getName());
|
||||
copy.setHost(getHost());
|
||||
copy.setPort(getPort());
|
||||
copy.setInline(getInline());
|
||||
copy.setPassword(getPassword());
|
||||
copy.setDelay(getDelay());
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.audio.broadcast.icecast.codec;
|
||||
|
||||
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.convert.InputAudioFormat;
|
||||
import io.github.dsheirer.audio.convert.MP3Setting;
|
||||
import io.github.dsheirer.identifier.IdentifierCollection;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import org.apache.mina.core.RuntimeIoException;
|
||||
import org.apache.mina.core.buffer.IoBuffer;
|
||||
@@ -93,7 +94,7 @@ public class ShoutcastV1AudioBroadcaster extends AudioStreamingBroadcaster
|
||||
* Broadcasts the audio frame or sequence
|
||||
*/
|
||||
@Override
|
||||
protected void broadcastAudio(byte[] audio)
|
||||
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||
{
|
||||
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
|
||||
*/
|
||||
@Override
|
||||
protected void broadcastAudio(byte[] audio)
|
||||
protected void broadcastAudio(byte[] audio, IdentifierCollection identifierCollection)
|
||||
{
|
||||
//Dispatch any queued metadata messages
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.audio.broadcast.shoutcast.v2.ultravox;
|
||||
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -18,19 +18,19 @@
|
||||
*/
|
||||
package io.github.dsheirer.audio.convert;
|
||||
|
||||
import io.github.dsheirer.audio.AudioUtils;
|
||||
import io.github.dsheirer.dsp.filter.resample.RealResampler;
|
||||
import io.github.dsheirer.sample.ConversionUtils;
|
||||
import net.sourceforge.lame.lowlevel.LameEncoder;
|
||||
import net.sourceforge.lame.mp3.Lame;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.sourceforge.lame.lowlevel.LameEncoder;
|
||||
import net.sourceforge.lame.mp3.Lame;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Converts PCM audio packets to Mono, MP3 encoded audio
|
||||
@@ -45,16 +45,20 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
private byte[] mOutputFramesBuffer;
|
||||
private InputAudioFormat mInputAudioFormat;
|
||||
|
||||
private boolean mNormalizeAudio;
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param inputAudioFormat for the desired input sample rate and bit size (resampled from default 8 kHz as needed)
|
||||
* @param setting to configure the LAME encoder
|
||||
* @param normalizeAudio to normalize the audio gain prior to encoding
|
||||
*/
|
||||
public MP3AudioConverter(InputAudioFormat inputAudioFormat, MP3Setting setting)
|
||||
public MP3AudioConverter(InputAudioFormat inputAudioFormat, MP3Setting setting, boolean normalizeAudio)
|
||||
{
|
||||
mInputAudioFormat = inputAudioFormat;
|
||||
mEncoder = LameFactory.getLameEncoder(inputAudioFormat, setting);
|
||||
mNormalizeAudio = normalizeAudio;
|
||||
|
||||
//Resampling is only required if desired input sample rate is not system default of 8kHz
|
||||
if(inputAudioFormat != InputAudioFormat.SR_8000 && inputAudioFormat != InputAudioFormat.SR_32_8000)
|
||||
@@ -74,6 +78,11 @@ public class MP3AudioConverter implements IAudioConverter
|
||||
{
|
||||
List<byte[]> converted = new ArrayList<>();
|
||||
|
||||
if(mNormalizeAudio)
|
||||
{
|
||||
audioPackets = AudioUtils.normalize(audioPackets);
|
||||
}
|
||||
|
||||
if(mResampler != null)
|
||||
{
|
||||
audioPackets = mResampler.resample(audioPackets);
|
||||
|
||||
@@ -34,8 +34,8 @@ public enum MP3Setting
|
||||
CBR_16(false, 16, "CBR - Constant Bit Rate 16 kbps (default)"),
|
||||
CBR_32(false, 32, "CBR - Constant Bit Rate 32 kbps"),
|
||||
ABR_56(true, 56, "ABR - Average Bit Rate 56 kbps"),
|
||||
VBR_5(true, Lame.QUALITY_MIDDLE, "VBR - Middle Quality (5)"),
|
||||
VBR_7(true, Lame.QUALITY_LOW, "VBR - Low Quality (7)");
|
||||
VBR_5(true, Lame.QUALITY_MIDDLE, "VBR - Variable Bit Rate - Better Quality"),
|
||||
VBR_7(true, Lame.QUALITY_LOW, "VBR - Variable Bit Rate - Good Quality");
|
||||
|
||||
private boolean mVariableBitRate;
|
||||
private int mSetting;
|
||||
|
||||
@@ -18,11 +18,10 @@
|
||||
*/
|
||||
package io.github.dsheirer.audio.convert;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class MP3SilenceGenerator implements ISilenceGenerator
|
||||
{
|
||||
@@ -40,7 +39,7 @@ public class MP3SilenceGenerator implements ISilenceGenerator
|
||||
public MP3SilenceGenerator(InputAudioFormat inputAudioFormat, MP3Setting setting)
|
||||
{
|
||||
mInputAudioFormat = inputAudioFormat;
|
||||
mMP3AudioConverter = new MP3AudioConverter(inputAudioFormat, setting);
|
||||
mMP3AudioConverter = new MP3AudioConverter(inputAudioFormat, setting, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.convert.thumbdv.message;
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.convert.thumbdv.message.response;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* sdrtrunk
|
||||
* 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 License as published by
|
||||
@@ -15,7 +14,7 @@
|
||||
*
|
||||
* 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.playback;
|
||||
|
||||
@@ -30,7 +29,6 @@ import io.github.dsheirer.icon.IconModel;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.mixer.MixerChannelConfiguration;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
import jiconfont.swing.IconFontSwing;
|
||||
@@ -69,7 +67,6 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
|
||||
|
||||
private IconModel mIconModel;
|
||||
private SettingsManager mSettingsManager;
|
||||
private SourceManager mSourceManager;
|
||||
private IAudioController mController;
|
||||
private AliasModel mAliasModel;
|
||||
private UserPreferences mUserPreferences;
|
||||
@@ -78,11 +75,10 @@ public class AudioPanel extends JPanel implements Listener<AudioEvent>
|
||||
private AudioChannelsPanel mAudioChannelsPanel;
|
||||
|
||||
public AudioPanel(IconModel iconModel, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||
SourceManager sourceManager, IAudioController controller, AliasModel aliasModel)
|
||||
IAudioController controller, AliasModel aliasModel)
|
||||
{
|
||||
mIconModel = iconModel;
|
||||
mSettingsManager = settingsManager;
|
||||
mSourceManager = sourceManager;
|
||||
mController = controller;
|
||||
mAliasModel = aliasModel;
|
||||
mUserPreferences = userPreferences;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class BinaryMessage extends BitSet
|
||||
* Logical (ie constructed) size of this bitset, despite the actual size of
|
||||
* 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
|
||||
@@ -43,21 +43,21 @@ public class BinaryMessage extends BitSet
|
||||
*/
|
||||
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
|
||||
* message to an EDAC function.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
super(size);
|
||||
@@ -214,9 +214,7 @@ public class BinaryMessage extends BitSet
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a (new) copy of this bitsetbuffer
|
||||
*
|
||||
* @return
|
||||
* @return a (new) copy of this binary message
|
||||
*/
|
||||
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
|
||||
* 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 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.
|
||||
* 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/>
|
||||
******************************************************************************/
|
||||
* 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.buffer;
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.buffer;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.channel.metadata;
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.channel.state;
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.channel.state;
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.channel.state;
|
||||
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.channel.state;
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.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
|
||||
* 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.preference.UserPreferences;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.tuner.TunerViewPanel;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import io.github.dsheirer.source.tuner.ui.TunerViewPanel;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
import jiconfont.swing.IconFontSwing;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
@@ -59,13 +59,13 @@ public class ControllerPanel extends JPanel
|
||||
|
||||
public ControllerPanel(PlaylistManager playlistManager, AudioPlaybackManager audioPlaybackManager,
|
||||
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());
|
||||
mNowPlayingPanel = new NowPlayingPanel(playlistManager, iconModel, userPreferences);
|
||||
mMapPanel = new MapPanel(mapService, playlistManager.getAliasModel(), iconModel, settingsManager);
|
||||
mTunerManagerPanel = new TunerViewPanel(sourceManager.getTunerModel(), userPreferences);
|
||||
mTunerManagerPanel = new TunerViewPanel(tunerManager, userPreferences);
|
||||
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.controller.channel;
|
||||
|
||||
@@ -28,6 +25,7 @@ import io.github.dsheirer.channel.metadata.ChannelAndMetadata;
|
||||
import io.github.dsheirer.channel.metadata.ChannelMetadata;
|
||||
import io.github.dsheirer.channel.metadata.ChannelMetadataModel;
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStartProcessingRequest;
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
|
||||
import io.github.dsheirer.controller.channel.event.PreloadDataContent;
|
||||
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
||||
import io.github.dsheirer.identifier.Form;
|
||||
@@ -47,14 +45,12 @@ import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.source.Source;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
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.SourceConfigTunerMultipleFrequency;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import javafx.application.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -64,6 +60,9 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import javafx.application.Platform;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Channel processing manager handles all starting and stopping of channel decoding. A processing chain is created
|
||||
@@ -86,7 +85,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
private ChannelMapModel mChannelMapModel;
|
||||
private ChannelMetadataModel mChannelMetadataModel;
|
||||
private EventLogManager mEventLogManager;
|
||||
private SourceManager mSourceManager;
|
||||
private TunerManager mTunerManager;
|
||||
private AliasModel mAliasModel;
|
||||
private UserPreferences mUserPreferences;
|
||||
private List<Long> mLoggedFrequencies = new ArrayList<>();
|
||||
@@ -97,16 +96,16 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
*
|
||||
* @param channelMapModel containing channel maps defined by the user
|
||||
* @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 userPreferences for user defined behavior and settings
|
||||
*/
|
||||
public ChannelProcessingManager(ChannelMapModel channelMapModel, EventLogManager eventLogManager,
|
||||
SourceManager sourceManager, AliasModel aliasModel, UserPreferences userPreferences)
|
||||
TunerManager tunerManager, AliasModel aliasModel, UserPreferences userPreferences)
|
||||
{
|
||||
mChannelMapModel = channelMapModel;
|
||||
mEventLogManager = eventLogManager;
|
||||
mSourceManager = sourceManager;
|
||||
mTunerManager = tunerManager;
|
||||
mAliasModel = aliasModel;
|
||||
mUserPreferences = userPreferences;
|
||||
mChannelMetadataModel = new ChannelMetadataModel();
|
||||
@@ -126,7 +125,20 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
*/
|
||||
private boolean isProcessing(Channel channel)
|
||||
{
|
||||
return mProcessingChains.containsKey(channel) && mProcessingChains.get(channel).isProcessing();
|
||||
boolean isProcessing = false;
|
||||
|
||||
mLock.lock();
|
||||
|
||||
try
|
||||
{
|
||||
isProcessing = mProcessingChains.containsKey(channel) && mProcessingChains.get(channel).isProcessing();
|
||||
}
|
||||
finally
|
||||
{
|
||||
mLock.unlock();
|
||||
}
|
||||
|
||||
return isProcessing;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,18 +167,60 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
*/
|
||||
public Channel getChannel(ProcessingChain processingChain)
|
||||
{
|
||||
Channel channel = null;
|
||||
|
||||
if(processingChain != null)
|
||||
{
|
||||
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChains.entrySet())
|
||||
mLock.lock();
|
||||
|
||||
try
|
||||
{
|
||||
if(entry.getValue() == processingChain)
|
||||
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChains.entrySet())
|
||||
{
|
||||
return entry.getKey();
|
||||
if(entry.getValue() == processingChain)
|
||||
{
|
||||
channel = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
mLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the channel associated with the processing chain that is consuming from the tuner channel source
|
||||
* @param tunerChannelSource to find the channel
|
||||
* @return channel
|
||||
*/
|
||||
private Channel getChannel(TunerChannelSource tunerChannelSource)
|
||||
{
|
||||
Channel channel = null;
|
||||
|
||||
mLock.lock();
|
||||
|
||||
try
|
||||
{
|
||||
for(Map.Entry<Channel,ProcessingChain> entry : mProcessingChains.entrySet())
|
||||
{
|
||||
if(entry.getValue().hasSource(tunerChannelSource))
|
||||
{
|
||||
channel = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
mLock.unlock();
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,6 +329,28 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to stop a channel that is currently processing
|
||||
* @param request with the tuner channel source feeding the channel to be stopped.
|
||||
*/
|
||||
@Subscribe
|
||||
public void stopChannelRequest(ChannelStopProcessingRequest request)
|
||||
{
|
||||
Channel channel = getChannel(request.getTunerChannelSource());
|
||||
|
||||
if(channel != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
stop(channel);
|
||||
}
|
||||
catch(ChannelException ce)
|
||||
{
|
||||
mLog.error("Error stopping channel [" + channel + "]", ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the specified channel
|
||||
* @param channel to stop
|
||||
@@ -303,7 +379,7 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
|
||||
try
|
||||
{
|
||||
source = mSourceManager.getSource(channel.getSourceConfiguration(),
|
||||
source = mTunerManager.getSource(channel.getSourceConfiguration(),
|
||||
channel.getDecodeConfiguration().getChannelSpecification());
|
||||
}
|
||||
catch(SourceException se)
|
||||
@@ -439,8 +515,15 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
{
|
||||
processingChain.start();
|
||||
|
||||
//This has to be done on the FX event thread when the playlist editor is constructed
|
||||
Platform.runLater(() -> channel.setProcessing(true));
|
||||
if(GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
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));
|
||||
}
|
||||
@@ -526,13 +609,20 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
*/
|
||||
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);
|
||||
|
||||
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
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
@@ -558,10 +648,6 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ChannelException("Channel is not currently playing");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -736,7 +822,14 @@ public class ChannelProcessingManager implements Listener<ChannelEvent>
|
||||
|
||||
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
|
||||
{
|
||||
mLog.warn("Source event error - stopping channel [" + toShutdown.getName() + "]");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.controller.channel.event;
|
||||
|
||||
import io.github.dsheirer.module.ModuleEventBusMessage;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
|
||||
/**
|
||||
* Request to stop processing a channel for a specific tuner channel source
|
||||
*/
|
||||
public class ChannelStopProcessingRequest extends ModuleEventBusMessage
|
||||
{
|
||||
private TunerChannelSource mTunerChannelSource;
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param tunerChannelSource for the channel to stop
|
||||
*/
|
||||
public ChannelStopProcessingRequest(TunerChannelSource tunerChannelSource)
|
||||
{
|
||||
mTunerChannelSource = tunerChannelSource;
|
||||
}
|
||||
|
||||
public TunerChannelSource getTunerChannelSource()
|
||||
{
|
||||
return mTunerChannelSource;
|
||||
}
|
||||
}
|
||||
@@ -21,11 +21,13 @@ package io.github.dsheirer.dsp.filter.channelizer;
|
||||
import io.github.dsheirer.buffer.INativeBuffer;
|
||||
import io.github.dsheirer.buffer.INativeBufferProvider;
|
||||
import io.github.dsheirer.buffer.NativeBufferPoisonPill;
|
||||
import io.github.dsheirer.controller.channel.event.ChannelStopProcessingRequest;
|
||||
import io.github.dsheirer.dsp.filter.FilterFactory;
|
||||
import io.github.dsheirer.dsp.filter.channelizer.output.IPolyphaseChannelOutputProcessor;
|
||||
import io.github.dsheirer.dsp.filter.channelizer.output.OneChannelOutputProcessor;
|
||||
import io.github.dsheirer.dsp.filter.channelizer.output.TwoChannelOutputProcessor;
|
||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.InterleavedComplexSamples;
|
||||
@@ -37,10 +39,7 @@ import io.github.dsheirer.source.tuner.TunerController;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
|
||||
import io.github.dsheirer.util.Dispatcher;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -50,6 +49,9 @@ import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Polyphase Channel Manager is a DDC channel manager and complex buffer queue/processor for a tuner. This class
|
||||
@@ -84,6 +86,7 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
private NativeBufferReceiver mNativeBufferReceiver = new NativeBufferReceiver();
|
||||
private Dispatcher mBufferDispatcher;
|
||||
private Map<Integer,float[]> mOutputProcessorFilters = new HashMap<>();
|
||||
private boolean mRunning = true;
|
||||
|
||||
/**
|
||||
* Creates a polyphase channel manager instance.
|
||||
@@ -126,6 +129,18 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
this(tunerController, tunerController.getFrequency(), tunerController.getSampleRate());
|
||||
}
|
||||
|
||||
public void stopAllChannels()
|
||||
{
|
||||
mRunning = false;
|
||||
|
||||
List<TunerChannelSource> toStop = new ArrayList<>(mChannelSources);
|
||||
|
||||
for(TunerChannelSource tunerChannelSource: toStop)
|
||||
{
|
||||
MyEventBus.getGlobalEventBus().post(new ChannelStopProcessingRequest(tunerChannelSource));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@@ -164,24 +179,27 @@ public class PolyphaseChannelManager implements ISourceEventProcessor
|
||||
{
|
||||
PolyphaseChannelSource channelSource = null;
|
||||
|
||||
List<Integer> polyphaseIndexes = mChannelCalculator.getChannelIndexes(tunerChannel);
|
||||
|
||||
IPolyphaseChannelOutputProcessor outputProcessor = getOutputProcessor(polyphaseIndexes);
|
||||
|
||||
if(outputProcessor != null)
|
||||
if(mRunning)
|
||||
{
|
||||
long centerFrequency = mChannelCalculator.getCenterFrequencyForIndexes(polyphaseIndexes);
|
||||
List<Integer> polyphaseIndexes = mChannelCalculator.getChannelIndexes(tunerChannel);
|
||||
|
||||
try
|
||||
{
|
||||
channelSource = new PolyphaseChannelSource(tunerChannel, outputProcessor, mChannelSourceEventListener,
|
||||
mChannelCalculator.getChannelSampleRate(), centerFrequency);
|
||||
IPolyphaseChannelOutputProcessor outputProcessor = getOutputProcessor(polyphaseIndexes);
|
||||
|
||||
mChannelSources.add(channelSource);
|
||||
}
|
||||
catch(FilterDesignException fde)
|
||||
if(outputProcessor != null)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(requestedRate < 2)
|
||||
if(requestedRate < 0)
|
||||
{
|
||||
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
|
||||
* 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;
|
||||
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.dsp.filter.fir.remez;
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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 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.
|
||||
* 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/>
|
||||
******************************************************************************/
|
||||
* 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.edac;
|
||||
|
||||
import io.github.dsheirer.bits.BinaryMessage;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class FilterEditorPanel<T> extends JPanel
|
||||
List<IFilter<T>> filters = filterSet.getFilters();
|
||||
|
||||
/* 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)
|
||||
{
|
||||
@@ -98,7 +98,7 @@ public class FilterEditorPanel<T> extends JPanel
|
||||
{
|
||||
List<FilterElement<?>> elements = filter.getFilterElements();
|
||||
|
||||
elements.sort(Comparator.comparing(FilterElement::toString));
|
||||
elements.sort(Comparator.comparing(FilterElement::getName));
|
||||
|
||||
for(FilterElement<?> element : elements)
|
||||
{
|
||||
|
||||
@@ -46,13 +46,14 @@ public class FilterSet<T> implements IFilter<T>
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,7 @@ import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.tuner.TunerModel;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
@@ -79,6 +76,7 @@ public class JavaFxWindowManager extends Application
|
||||
private JmbeEditor mJmbeEditor;
|
||||
private PlaylistEditor mPlaylistEditor;
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private TunerManager mTunerManager;
|
||||
private UserPreferences mUserPreferences;
|
||||
private UserPreferencesEditor mUserPreferencesEditor;
|
||||
|
||||
@@ -91,9 +89,10 @@ public class JavaFxWindowManager extends Application
|
||||
/**
|
||||
* 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;
|
||||
mTunerManager = tunerManager;
|
||||
mPlaylistManager = playlistManager;
|
||||
|
||||
setup();
|
||||
@@ -106,12 +105,10 @@ public class JavaFxWindowManager extends Application
|
||||
{
|
||||
mUserPreferences = new UserPreferences();
|
||||
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);
|
||||
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();
|
||||
setup();
|
||||
}
|
||||
@@ -274,7 +271,7 @@ public class JavaFxWindowManager extends Application
|
||||
{
|
||||
if(mPlaylistEditor == null)
|
||||
{
|
||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mUserPreferences);
|
||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||
}
|
||||
|
||||
return mPlaylistEditor;
|
||||
|
||||
@@ -29,6 +29,7 @@ import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
||||
import io.github.dsheirer.controller.ControllerPanel;
|
||||
import io.github.dsheirer.controller.channel.Channel;
|
||||
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.eventbus.MyEventBus;
|
||||
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.sample.Listener;
|
||||
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.TunerEvent;
|
||||
import io.github.dsheirer.source.tuner.TunerModel;
|
||||
import io.github.dsheirer.source.tuner.TunerSpectralDisplayManager;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import io.github.dsheirer.source.tuner.ui.TunerSpectralDisplayManager;
|
||||
import io.github.dsheirer.spectrum.ClearTunerMenuItem;
|
||||
import io.github.dsheirer.spectrum.ShowTunerMenuItem;
|
||||
import io.github.dsheirer.spectrum.SpectralDisplayPanel;
|
||||
@@ -68,11 +68,25 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.MenuListener;
|
||||
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.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
@@ -104,19 +118,24 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
private ControllerPanel mControllerPanel;
|
||||
private IconModel mIconModel = new IconModel();
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private SourceManager mSourceManager;
|
||||
private SettingsManager mSettingsManager;
|
||||
private SpectralDisplayPanel mSpectralPanel;
|
||||
private JFrame mMainGui = new JFrame();
|
||||
private JFrame mMainGui;
|
||||
private JideSplitPane mSplitPane;
|
||||
private JavaFxWindowManager mJavaFxWindowManager;
|
||||
private UserPreferences mUserPreferences = new UserPreferences();
|
||||
private TunerManager mTunerManager;
|
||||
private ApplicationLog mApplicationLog;
|
||||
|
||||
private String mTitle;
|
||||
|
||||
public SDRTrunk()
|
||||
{
|
||||
if(!GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
mMainGui = new JFrame();
|
||||
}
|
||||
|
||||
mApplicationLog = new ApplicationLog(mUserPreferences);
|
||||
mApplicationLog.start();
|
||||
|
||||
@@ -154,16 +173,19 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
//Register FontAwesome so we can use the fonts in Swing windows
|
||||
IconFontSwing.register(FontAwesome.getIconFont());
|
||||
|
||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
||||
mTunerManager = new TunerManager(mUserPreferences);
|
||||
mTunerManager.start();
|
||||
|
||||
mSettingsManager = new SettingsManager(tunerConfigurationModel);
|
||||
mSourceManager = new SourceManager(tunerModel, mSettingsManager, mUserPreferences);
|
||||
mSettingsManager = new SettingsManager();
|
||||
|
||||
AliasModel aliasModel = new AliasModel();
|
||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||
mPlaylistManager = new PlaylistManager(mUserPreferences, mSourceManager, aliasModel, eventLogManager, mIconModel);
|
||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mPlaylistManager);
|
||||
mPlaylistManager = new PlaylistManager(mUserPreferences, mTunerManager, aliasModel, eventLogManager, mIconModel);
|
||||
|
||||
if(!GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mTunerManager, mPlaylistManager);
|
||||
}
|
||||
|
||||
CalibrationManager calibrationManager = CalibrationManager.getInstance(mUserPreferences);
|
||||
final boolean calibrating = !calibrationManager.isCalibrated() &&
|
||||
@@ -190,32 +212,45 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
MapService mapService = new MapService(mIconModel);
|
||||
mPlaylistManager.getChannelProcessingManager().addDecodeEventListener(mapService);
|
||||
|
||||
mControllerPanel = new ControllerPanel(mPlaylistManager, audioPlaybackManager, mIconModel, mapService,
|
||||
mSettingsManager, mSourceManager, mUserPreferences);
|
||||
if(!GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
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,
|
||||
mPlaylistManager, mSettingsManager, tunerModel);
|
||||
tunerModel.addListener(tunerSpectralDisplayManager);
|
||||
tunerModel.addListener(this);
|
||||
mPlaylistManager, mSettingsManager, mTunerManager.getDiscoveredTunerModel());
|
||||
mTunerManager.getDiscoveredTunerModel().addListener(tunerSpectralDisplayManager);
|
||||
mTunerManager.getDiscoveredTunerModel().addListener(this);
|
||||
|
||||
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
|
||||
initGUI();
|
||||
|
||||
tunerModel.requestFirstTunerDisplay();
|
||||
//Initialize the GUI
|
||||
initGUI();
|
||||
}
|
||||
|
||||
//Start the gui
|
||||
EventQueue.invokeLater(() -> {
|
||||
try
|
||||
{
|
||||
mMainGui.setVisible(true);
|
||||
if(!GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
mMainGui.setVisible(true);
|
||||
Tuner tuner = tunerSpectralDisplayManager.showFirstTuner();
|
||||
updateTitle(tuner);
|
||||
}
|
||||
|
||||
if(calibrating)
|
||||
if(calibrating && !GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
Platform.runLater(() ->
|
||||
{
|
||||
@@ -256,8 +291,25 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
|
||||
if(channels.size() > 0)
|
||||
{
|
||||
ChannelAutoStartFrame autoStartFrame = new ChannelAutoStartFrame(mPlaylistManager.getChannelProcessingManager(),
|
||||
channels);
|
||||
if(GraphicsEnvironment.isHeadless())
|
||||
{
|
||||
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 ...");
|
||||
mSpectralPanel.clearTuner();
|
||||
mSourceManager.shutdown();
|
||||
mLog.info("Stopping tuners ...");
|
||||
mTunerManager.stop();
|
||||
mLog.info("Shutdown complete.");
|
||||
mApplicationLog.stop();
|
||||
}
|
||||
@@ -572,7 +625,23 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
{
|
||||
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();
|
||||
|
||||
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.INativeBuffer;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
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.channel.TunerChannel;
|
||||
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.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
@@ -40,10 +39,16 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
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.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
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_FFT_FRAME_RATE = 20;
|
||||
|
||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
||||
private SettingsManager mSettingsManager = new SettingsManager();
|
||||
private JPanel mPrimaryPanel;
|
||||
private JPanel mControlPanel;
|
||||
private JLabel mToneFrequencyLabel;
|
||||
@@ -78,7 +83,7 @@ public class ChannelizerViewer extends JFrame
|
||||
*/
|
||||
public ChannelizerViewer(int channelsPerRow)
|
||||
{
|
||||
mTestTuner = new TestTuner(new UserPreferences());
|
||||
mTestTuner = new TestTuner(new LoggingTunerErrorListener());
|
||||
mChannelCount = (int)(mTestTuner.getTunerController().getBandwidth() / CHANNEL_BANDWIDTH);
|
||||
mChannelsPerRow = channelsPerRow;
|
||||
|
||||
@@ -518,7 +523,7 @@ public class ChannelizerViewer extends JFrame
|
||||
}
|
||||
else
|
||||
{
|
||||
TestTuner tuner = new TestTuner(new UserPreferences());
|
||||
TestTuner tuner = new TestTuner(new LoggingTunerErrorListener());
|
||||
|
||||
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.INativeBuffer;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
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.channel.ChannelSpecification;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
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.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
@@ -41,10 +40,18 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
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.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
@@ -56,7 +63,7 @@ public class ChannelizerViewer2 extends JFrame
|
||||
|
||||
private static final int CHANNEL_BANDWIDTH = 12500;
|
||||
|
||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
||||
private SettingsManager mSettingsManager = new SettingsManager();
|
||||
private JPanel mPrimaryPanel;
|
||||
private JPanel mControlPanel;
|
||||
private JButton mTopFrameAddChannelButton;
|
||||
@@ -68,7 +75,7 @@ public class ChannelizerViewer2 extends JFrame
|
||||
private ChannelArrayPanel mBottomChannelArrayPanel;
|
||||
private DFTSize mMainPanelDFTSize = DFTSize.FFT32768;
|
||||
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.
|
||||
|
||||
@@ -20,18 +20,17 @@ package io.github.dsheirer.gui.channelizer;
|
||||
|
||||
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
||||
import io.github.dsheirer.buffer.INativeBuffer;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
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.channel.ChannelSpecification;
|
||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
||||
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.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
@@ -41,10 +40,16 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
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.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
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_FFT_FRAME_RATE = 20;
|
||||
|
||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
||||
private SettingsManager mSettingsManager = new SettingsManager();
|
||||
private JPanel mPrimaryPanel;
|
||||
private JPanel mControlPanel;
|
||||
private JLabel mToneFrequencyLabel;
|
||||
@@ -77,7 +82,7 @@ public class HeterodyneChannelizerViewer extends JFrame
|
||||
*/
|
||||
public HeterodyneChannelizerViewer()
|
||||
{
|
||||
mTestTuner = new TestTuner(new UserPreferences());
|
||||
mTestTuner = new TestTuner(new LoggingTunerErrorListener());
|
||||
mChannelCount = 5;
|
||||
mChannelsPerRow = 5;
|
||||
init();
|
||||
@@ -516,7 +521,7 @@ public class HeterodyneChannelizerViewer extends JFrame
|
||||
}
|
||||
else
|
||||
{
|
||||
TestTuner tuner = new TestTuner(new UserPreferences());
|
||||
TestTuner tuner = new TestTuner(new LoggingTunerErrorListener());
|
||||
|
||||
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.complex.ComplexSamples;
|
||||
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.DFTSize;
|
||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||
@@ -39,10 +38,15 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
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.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
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 DATA_GENERATOR_FRAME_RATE = 50; //frames per second
|
||||
|
||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
||||
private SettingsManager mSettingsManager = new SettingsManager();
|
||||
private JPanel mPrimaryPanel;
|
||||
private PrimarySpectrumPanel mPrimarySpectrumPanel;
|
||||
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
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
******************************************************************************/
|
||||
* ****************************************************************************
|
||||
*/
|
||||
package io.github.dsheirer.gui.control;
|
||||
|
||||
import io.github.dsheirer.source.ISourceEventProcessor;
|
||||
@@ -69,12 +70,6 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
init();
|
||||
}
|
||||
|
||||
public JFrequencyControl(long value)
|
||||
{
|
||||
this();
|
||||
mFrequency = value;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[]0[]", ""));
|
||||
@@ -91,8 +86,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
}
|
||||
catch(ParseException e)
|
||||
{
|
||||
mLog.error("JFrequencyControl - parse exception "
|
||||
+ "constructing a digit - " + e);
|
||||
mLog.error("JFrequencyControl - parse exception constructing a digit - " + e);
|
||||
}
|
||||
|
||||
if(digit != null)
|
||||
@@ -105,15 +99,11 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
|
||||
if(x == 6)
|
||||
{
|
||||
JLabel period = new JLabel(".");
|
||||
|
||||
add(period);
|
||||
add(new JLabel(". "));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add(new JLabel(" MHz"));
|
||||
|
||||
/**
|
||||
* 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
|
||||
Image cursorImage = Toolkit.getDefaultToolkit().createImage(imageByte);
|
||||
|
||||
mBlankCursor = Toolkit.getDefaultToolkit()
|
||||
.createCustomCursor(cursorImage, new Point(0, 0), "cursor");
|
||||
|
||||
setTooltip(false);
|
||||
|
||||
mBlankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImage, new Point(0, 0), "cursor");
|
||||
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
|
||||
* 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())
|
||||
{
|
||||
case NOTIFICATION_FREQUENCY_CHANGE:
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@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);
|
||||
}
|
||||
});
|
||||
EventQueue.invokeLater(() -> setFrequency(event.getValue().longValue(), false));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -251,11 +188,30 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the source event listener
|
||||
* @param 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)
|
||||
{
|
||||
mProcessors.remove(processor);
|
||||
@@ -272,7 +228,7 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
super("0");
|
||||
|
||||
mPower = position;
|
||||
|
||||
setToolTipText(getTooltip(mPower));
|
||||
Listener listener = new Listener();
|
||||
|
||||
this.addKeyListener(listener);
|
||||
@@ -280,6 +236,49 @@ public class JFrequencyControl extends JPanel implements ISourceEventProcessor
|
||||
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
|
||||
* 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-2019 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 License as published by
|
||||
@@ -15,7 +14,7 @@
|
||||
*
|
||||
* 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.instrument.decoder;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
||||
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
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.TimeStamp;
|
||||
import javafx.application.Platform;
|
||||
@@ -65,6 +66,7 @@ public class PlaylistEditor extends BorderPane
|
||||
private static final Logger mLog = LoggerFactory.getLogger(PlaylistEditor.class);
|
||||
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private TunerManager mTunerManager;
|
||||
private UserPreferences mUserPreferences;
|
||||
private MenuBar mMenuBar;
|
||||
private TabPane mTabPane;
|
||||
@@ -79,11 +81,13 @@ public class PlaylistEditor extends BorderPane
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager for alias and channel models
|
||||
* @param tunerManager for tuners
|
||||
* @param userPreferences for settings
|
||||
*/
|
||||
public PlaylistEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||
public PlaylistEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||
{
|
||||
mPlaylistManager = playlistManager;
|
||||
mTunerManager = tunerManager;
|
||||
mUserPreferences = userPreferences;
|
||||
|
||||
//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)
|
||||
{
|
||||
mChannelEditor = new ChannelEditor(mPlaylistManager, mUserPreferences);
|
||||
mChannelEditor = new ChannelEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||
}
|
||||
|
||||
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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -20,17 +20,12 @@
|
||||
package io.github.dsheirer.gui.playlist;
|
||||
|
||||
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.icon.IconModel;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.tuner.TunerModel;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
@@ -43,6 +38,7 @@ public class PlaylistEditorApplication extends Application
|
||||
{
|
||||
private Stage mStage;
|
||||
private Parent mPlaylistEditor;
|
||||
private TunerManager mTunerManager;
|
||||
private UserPreferences mUserPreferences = new UserPreferences();
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private JavaFxWindowManager mJavaFxWindowManager;
|
||||
@@ -50,17 +46,13 @@ public class PlaylistEditorApplication extends Application
|
||||
public PlaylistEditorApplication()
|
||||
{
|
||||
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);
|
||||
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();
|
||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mPlaylistManager);
|
||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mTunerManager, mPlaylistManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,7 +69,7 @@ public class PlaylistEditorApplication extends Application
|
||||
{
|
||||
if(mPlaylistEditor == null)
|
||||
{
|
||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mUserPreferences);
|
||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mTunerManager, mUserPreferences);
|
||||
}
|
||||
|
||||
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
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -34,6 +31,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -59,11 +57,14 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* 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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getRecordPane());
|
||||
@@ -138,7 +139,7 @@ public class AMConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -36,7 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||
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 javafx.application.Platform;
|
||||
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 PlaylistManager mPlaylistManager;
|
||||
protected TunerManager mTunerManager;
|
||||
protected UserPreferences mUserPreferences;
|
||||
protected EditorModificationListener mEditorModificationListener = new EditorModificationListener();
|
||||
private Button mPlayButton;
|
||||
@@ -100,9 +101,17 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
private IconNode mStopGraphicNode;
|
||||
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;
|
||||
mTunerManager = tunerManager;
|
||||
mUserPreferences = userPreferences;
|
||||
|
||||
setMaxWidth(Double.MAX_VALUE);
|
||||
@@ -236,11 +245,6 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
modifiedProperty().setValue(false);
|
||||
}
|
||||
|
||||
protected TunerModel getTunerModel()
|
||||
{
|
||||
return mPlaylistManager.getTunerModel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -25,6 +22,7 @@ package io.github.dsheirer.gui.playlist.channel;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -46,28 +44,28 @@ public class ChannelConfigurationEditorFactory
|
||||
* @return constructed editor
|
||||
*/
|
||||
public static ChannelConfigurationEditor getEditor(DecoderType decoderType, PlaylistManager playlistManager,
|
||||
UserPreferences userPreferences)
|
||||
TunerManager tunerManager, UserPreferences userPreferences)
|
||||
{
|
||||
switch(decoderType)
|
||||
{
|
||||
case AM:
|
||||
return new AMConfigurationEditor(playlistManager, userPreferences);
|
||||
return new AMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case DMR:
|
||||
return new DMRConfigurationEditor(playlistManager, userPreferences);
|
||||
return new DMRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case NBFM:
|
||||
return new NBFMConfigurationEditor(playlistManager, userPreferences);
|
||||
return new NBFMConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case LTR_NET:
|
||||
return new LTRNetConfigurationEditor(playlistManager, userPreferences);
|
||||
return new LTRNetConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case LTR:
|
||||
return new LTRConfigurationEditor(playlistManager, userPreferences);
|
||||
return new LTRConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case MPT1327:
|
||||
return new MPT1327ConfigurationEditor(playlistManager, userPreferences);
|
||||
return new MPT1327ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case PASSPORT:
|
||||
return new PassportConfigurationEditor(playlistManager, userPreferences);
|
||||
return new PassportConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case P25_PHASE1:
|
||||
return new P25P1ConfigurationEditor(playlistManager, userPreferences);
|
||||
return new P25P1ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
case P25_PHASE2:
|
||||
return new P25P2ConfigurationEditor(playlistManager, userPreferences);
|
||||
return new P25P2ConfigurationEditor(playlistManager, tunerManager, userPreferences);
|
||||
default:
|
||||
if(decoderType != null && !mLoggedUnrecognizedTypes.contains(decoderType))
|
||||
{
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -28,6 +25,7 @@ import io.github.dsheirer.module.decode.DecoderFactory;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
@@ -79,6 +77,7 @@ public class ChannelEditor extends SplitPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ChannelEditor.class);
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private TunerManager mTunerManager;
|
||||
private UserPreferences mUserPreferences;
|
||||
private TableView<Channel> mChannelTableView;
|
||||
private Label mPlaceholderLabel;
|
||||
@@ -102,11 +101,12 @@ public class ChannelEditor extends SplitPane
|
||||
* Constructs an instance
|
||||
* @param playlistManager containing playlists and channel configurations
|
||||
*/
|
||||
public ChannelEditor(PlaylistManager playlistManager, UserPreferences userPreferences)
|
||||
public ChannelEditor(PlaylistManager playlistManager, TunerManager tunerManager, UserPreferences userPreferences)
|
||||
{
|
||||
mPlaylistManager = playlistManager;
|
||||
mTunerManager = tunerManager;
|
||||
mUserPreferences = userPreferences;
|
||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, userPreferences);
|
||||
mUnknownConfigurationEditor = new UnknownConfigurationEditor(mPlaylistManager, mTunerManager, userPreferences);
|
||||
|
||||
HBox channelsBox = new HBox();
|
||||
channelsBox.setSpacing(10.0);
|
||||
@@ -203,7 +203,7 @@ public class ChannelEditor extends SplitPane
|
||||
if(editor == null)
|
||||
{
|
||||
editor = ChannelConfigurationEditorFactory.getEditor(channelDecoderType, mPlaylistManager,
|
||||
mUserPreferences);
|
||||
mTunerManager, mUserPreferences);
|
||||
|
||||
if(editor != null)
|
||||
{
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -40,6 +37,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -96,11 +94,14 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* 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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
@@ -240,7 +241,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
if(mSourceConfigurationEditor == null)
|
||||
{
|
||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
||||
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||
DecodeConfigDMR.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -74,12 +72,14 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager
|
||||
* @param userPreferences
|
||||
* @param playlistManager for playlists
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
@@ -210,7 +210,7 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -74,12 +72,13 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager
|
||||
* @param userPreferences
|
||||
* @param playlistManager for playlists
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
@@ -210,7 +209,7 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -40,6 +37,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.HPos;
|
||||
@@ -84,12 +82,14 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager
|
||||
* @param userPreferences
|
||||
* @param playlistManager for playlists
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
@@ -195,7 +195,7 @@ public class MPT1327ConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
if(mSourceConfigurationEditor == null)
|
||||
{
|
||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
||||
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||
DecodeConfigMPT1327.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -42,6 +39,7 @@ import io.github.dsheirer.protocol.Protocol;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
@@ -92,12 +90,14 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager
|
||||
* @param userPreferences
|
||||
* @param playlistManager for playlists
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
@@ -228,7 +228,7 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -38,6 +35,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.geometry.HPos;
|
||||
@@ -80,12 +78,14 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager
|
||||
* @param userPreferences
|
||||
* @param playlistManager for playlists
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
@@ -191,7 +191,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
if(mSourceConfigurationEditor == null)
|
||||
{
|
||||
mSourceConfigurationEditor = new FrequencyEditor(getTunerModel(),
|
||||
mSourceConfigurationEditor = new FrequencyEditor(mTunerManager,
|
||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MINIMUM_MS,
|
||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_MAXIMUM_MS,
|
||||
DecodeConfigP25Phase1.CHANNEL_ROTATION_DELAY_DEFAULT_MS);
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -39,6 +36,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
@@ -73,9 +71,10 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param playlistManager
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getEventLogPane());
|
||||
@@ -179,7 +178,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -38,6 +35,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.RecorderType;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TitledPane;
|
||||
@@ -69,9 +67,10 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
||||
* @param playlistManager
|
||||
* @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(getDecoderPane());
|
||||
getTitledPanesBox().getChildren().add(getAuxDecoderPane());
|
||||
@@ -155,7 +154,7 @@ public class PassportConfigurationEditor extends ChannelConfigurationEditor
|
||||
{
|
||||
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
|
||||
mSourceConfigurationEditor.modifiedProperty()
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.channel;
|
||||
@@ -30,6 +27,7 @@ import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -46,9 +44,10 @@ public class UnknownConfigurationEditor extends ChannelConfigurationEditor
|
||||
* Constructs an instance
|
||||
* @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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
* 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
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.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.SourceConfigTunerMultipleFrequency;
|
||||
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.manager.TunerManager;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
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 static final String NONE = "(none) ";
|
||||
private TunerModel mTunerModel;
|
||||
private TunerManager mTunerManager;
|
||||
private FrequencyBox mPrimaryFrequencyBox;
|
||||
private ObservableList<FrequencyBox> mFrequencyBoxes = FXCollections.observableArrayList();
|
||||
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
|
||||
* 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 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;
|
||||
mFrequencyRotationMinimum = minRotationDelay;
|
||||
mFrequencyRotationMaximum = maxRotationDelay;
|
||||
@@ -91,11 +88,11 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
||||
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
@@ -333,9 +330,9 @@ public class FrequencyEditor extends SourceConfigurationEditor<SourceConfigurati
|
||||
getPreferredTunerComboBox().getItems().clear();
|
||||
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
|
||||
* 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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
/**
|
||||
* Broadcastify calls API configuration editor
|
||||
@@ -47,6 +48,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
private TextField mApiKeyTextField;
|
||||
private TextField mHostTextField;
|
||||
private GridPane mEditorPane;
|
||||
private ToggleSwitch mTestEnabledToggleSwitch;
|
||||
private IntegerTextField mTestIntervalTextField;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
@@ -66,6 +69,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
getApiKeyTextField().setDisable(item == null);
|
||||
getHostTextField().setDisable(item == null);
|
||||
getMaxAgeTextField().setDisable(item == null);
|
||||
getTestEnabledToggleSwitch().setDisable(item == null);
|
||||
getTestIntervalTextField().setDisable(item == null);
|
||||
|
||||
if(item != null)
|
||||
{
|
||||
@@ -73,6 +78,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
getApiKeyTextField().setText(item.getApiKey());
|
||||
getHostTextField().setText(item.getHost());
|
||||
getMaxAgeTextField().set((int)(item.getMaximumRecordingAge() / 1000));
|
||||
getTestEnabledToggleSwitch().setSelected(item.isTestEnabled());
|
||||
getTestIntervalTextField().set(item.getTestInterval());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -80,6 +87,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
getApiKeyTextField().setText(null);
|
||||
getHostTextField().setText(null);
|
||||
getMaxAgeTextField().set(0);
|
||||
getTestEnabledToggleSwitch().setSelected(false);
|
||||
getTestIntervalTextField().set(15);
|
||||
}
|
||||
|
||||
modifiedProperty().set(false);
|
||||
@@ -100,6 +109,8 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
getItem().setHost(getHostTextField().getText());
|
||||
getItem().setApiKey(getApiKeyTextField().getText());
|
||||
getItem().setMaximumRecordingAge(getMaxAgeTextField().get() * 1000);
|
||||
getItem().setTestEnabled(getTestEnabledToggleSwitch().isSelected());
|
||||
getItem().setTestInterval(getTestIntervalTextField().get());
|
||||
}
|
||||
|
||||
super.save();
|
||||
@@ -177,6 +188,22 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
GridPane.setConstraints(getMaxAgeTextField(), 1, row);
|
||||
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);
|
||||
mEditorPane.getChildren().add(getTestButton());
|
||||
}
|
||||
@@ -232,6 +259,31 @@ public class BroadcastifyCallEditor extends AbstractBroadcastEditor<Broadcastify
|
||||
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()
|
||||
{
|
||||
if(mTestButton == null)
|
||||
|
||||
@@ -30,6 +30,7 @@ import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
/**
|
||||
* Icecast streaming configuration editor
|
||||
@@ -37,6 +38,7 @@ import javafx.scene.layout.GridPane;
|
||||
public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastConfiguration>
|
||||
{
|
||||
private GridPane mEditorPane;
|
||||
private ToggleSwitch mInlineToggleSwitch;
|
||||
private TextField mMountPointTextField;
|
||||
private TextField mUserNameTextField;
|
||||
private TextField mDescriptionTextField;
|
||||
@@ -52,6 +54,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
public void setItem(IcecastConfiguration item)
|
||||
{
|
||||
getMountPointTextField().setDisable(item == null);
|
||||
getInlineToggleSwitch().setDisable(item == null);
|
||||
getUserNameTextField().setDisable(item == null);
|
||||
getDescriptionTextField().setDisable(item == null);
|
||||
getGenreTextField().setDisable(item == null);
|
||||
@@ -60,6 +63,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
if(item != null)
|
||||
{
|
||||
getMountPointTextField().setText(item.getMountPoint());
|
||||
getInlineToggleSwitch().setSelected(item.getInline());
|
||||
getUserNameTextField().setText(item.getUserName());
|
||||
getDescriptionTextField().setText(item.getDescription());
|
||||
getGenreTextField().setText(item.getGenre());
|
||||
@@ -68,6 +72,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
else
|
||||
{
|
||||
getMountPointTextField().setText(null);
|
||||
getInlineToggleSwitch().setSelected(false);
|
||||
getUserNameTextField().setText(null);
|
||||
getDescriptionTextField().setText(null);
|
||||
getGenreTextField().setText(null);
|
||||
@@ -83,6 +88,7 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
if(getItem() != null)
|
||||
{
|
||||
getItem().setMountPoint(getMountPointTextField().getText());
|
||||
getItem().setInline(getInlineToggleSwitch().isSelected());
|
||||
getItem().setUserName(getUserNameTextField().getText());
|
||||
getItem().setDescription(getDescriptionTextField().getText());
|
||||
getItem().setGenre(getGenreTextField().getText());
|
||||
@@ -150,6 +156,14 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
GridPane.setConstraints(getMountPointTextField(), 1, 3);
|
||||
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");
|
||||
GridPane.setHalignment(userNameLabel, HPos.RIGHT);
|
||||
GridPane.setConstraints(userNameLabel, 0, 4);
|
||||
@@ -226,6 +240,19 @@ public abstract class IcecastStreamEditor extends AbstractStreamEditor<IcecastCo
|
||||
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()
|
||||
{
|
||||
if(mUserNameTextField == null)
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.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
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
* 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.
|
||||
* 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/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* 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.preference;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* sdrtrunk
|
||||
* 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 License as published by
|
||||
@@ -15,7 +14,7 @@
|
||||
*
|
||||
* 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.preference.directory;
|
||||
@@ -63,6 +62,11 @@ public class DirectoryPreferenceEditor extends HBox
|
||||
private Button mResetApplicationLogsButton;
|
||||
private Label mApplicationLogsPathLabel;
|
||||
|
||||
private Label mConfigurationLabel;
|
||||
private Button mChangeConfigurationButton;
|
||||
private Button mResetConfigurationButton;
|
||||
private Label mConfigurationPathLabel;
|
||||
|
||||
private Label mEventLogsLabel;
|
||||
private Button mChangeEventLogsButton;
|
||||
private Button mResetEventLogsButton;
|
||||
@@ -154,6 +158,19 @@ public class DirectoryPreferenceEditor extends HBox
|
||||
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));
|
||||
mEditorPane.add(getEventLogsLabel(), 0, row);
|
||||
|
||||
@@ -365,6 +382,71 @@ public class DirectoryPreferenceEditor extends HBox
|
||||
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()
|
||||
{
|
||||
if(mEventLogsLabel == null)
|
||||
|
||||
@@ -25,6 +25,7 @@ import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.preference.mp3.MP3Preference;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.GridPane;
|
||||
@@ -44,7 +45,12 @@ public class MP3PreferenceEditor extends HBox
|
||||
private GridPane mEditorPane;
|
||||
private ComboBox<MP3Setting> mMP3SettingComboBox;
|
||||
private ComboBox<InputAudioFormat> mAudioSampleRateComboBox;
|
||||
private CheckBox mNormalizeAudioCheckBox;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param userPreferences
|
||||
*/
|
||||
public MP3PreferenceEditor(UserPreferences userPreferences)
|
||||
{
|
||||
mMP3Preference = userPreferences.getMP3Preference();
|
||||
@@ -65,6 +71,9 @@ public class MP3PreferenceEditor extends HBox
|
||||
Label topLabel = new Label("MP3 Encoder Preferences");
|
||||
mEditorPane.add(topLabel, 0, row++, 2, 1);
|
||||
|
||||
|
||||
mEditorPane.add(getNormalizeAudioCheckBox(), 1, row++);
|
||||
|
||||
Label label = new Label("(LAME) Encoder Setting:");
|
||||
GridPane.setHalignment(label, HPos.RIGHT);
|
||||
mEditorPane.add(label, 0, row);
|
||||
@@ -76,7 +85,7 @@ public class MP3PreferenceEditor extends HBox
|
||||
mEditorPane.add(getAudioSampleRateComboBox(), 1, row++);
|
||||
|
||||
Label notice = new Label("Note: sdrtrunk default 8 kHz audio rate is resampled to input sample rate before MP3 encoding");
|
||||
mEditorPane.add(notice, 0, row, 2, 1);
|
||||
mEditorPane.add(notice, 0, row++, 2, 1);
|
||||
}
|
||||
|
||||
return mEditorPane;
|
||||
@@ -109,4 +118,17 @@ public class MP3PreferenceEditor extends HBox
|
||||
|
||||
return mAudioSampleRateComboBox;
|
||||
}
|
||||
|
||||
private CheckBox getNormalizeAudioCheckBox()
|
||||
{
|
||||
if(mNormalizeAudioCheckBox == null)
|
||||
{
|
||||
mNormalizeAudioCheckBox = new CheckBox("Normalize Audio Before Encoding");
|
||||
mNormalizeAudioCheckBox.setSelected(mMP3Preference.isNormalizeAudioBeforeEncode());
|
||||
mNormalizeAudioCheckBox.onActionProperty().set(event ->
|
||||
mMP3Preference.setNormalizeAudioBeforeEncode(getNormalizeAudioCheckBox().isSelected()));
|
||||
}
|
||||
|
||||
return mNormalizeAudioCheckBox;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,20 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2022 Dennis Sheirer
|
||||
*
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
* 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.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
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
* 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.
|
||||
* 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/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* 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;
|
||||
|
||||
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
|
||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
* 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.
|
||||
* 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/>
|
||||
*
|
||||
******************************************************************************/
|
||||
* 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;
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user