diff --git a/src/main/java/io/github/dsheirer/controller/channel/Channel.java b/src/main/java/io/github/dsheirer/controller/channel/Channel.java
index a927a2015..ff40fe8f7 100644
--- a/src/main/java/io/github/dsheirer/controller/channel/Channel.java
+++ b/src/main/java/io/github/dsheirer/controller/channel/Channel.java
@@ -1,23 +1,20 @@
/*
+ * *****************************************************************************
+ * Copyright (C) 2014-2024 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
- * * *****************************************************************************
+ * 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
+ * ****************************************************************************
*/
package io.github.dsheirer.controller.channel;
@@ -35,13 +32,16 @@
import io.github.dsheirer.record.config.RecordConfiguration;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.source.SourceEvent;
-import io.github.dsheirer.source.SourceType;
import io.github.dsheirer.source.config.SourceConfigFactory;
import io.github.dsheirer.source.config.SourceConfigRecording;
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.channel.TunerChannel;
+import java.beans.Transient;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
@@ -55,9 +55,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.beans.Transient;
-import java.util.Objects;
-
@JacksonXmlRootElement(localName = "channel")
public class Channel extends Configuration implements Listener
{
@@ -88,7 +85,7 @@ public enum ChannelType
private BooleanProperty mAutoStart = new SimpleBooleanProperty();
private IntegerProperty mAutoStartOrder = new SimpleIntegerProperty();
private boolean mSelected;
- private TunerChannel mTunerChannel = null;
+ private List mTunerChannels = null;
private ChannelType mChannelType = ChannelType.STANDARD;
@@ -634,9 +631,8 @@ public void setSourceConfiguration(SourceConfiguration config)
updateFrequencies();
- //Clear the tune channel object so that it can be recreated if the
- //source configuration changes
- mTunerChannel = null;
+ //Clear the tune channels object so that it can be recreated if the source configuration changes
+ mTunerChannels = null;
}
/**
@@ -680,35 +676,50 @@ public void setRecordConfiguration(RecordConfiguration config)
}
/**
- * Convenience method to construct a tuner channel object representing a
- * tuner or recording source frequency and bandwidth that can be used by
- * application components for graphically representing this channel.
+ * Convenience method to construct a tuner channel object representing a tuner or recording source frequency and
+ * bandwidth that can be used by application components for graphically representing this channel.
*
- * If the source configuration is not a tuner or recording, this method
- * returns null.
+ * If the source configuration is not a tuner or recording, this method returns an empty list.
*/
@JsonIgnore
- public TunerChannel getTunerChannel()
+ public List getTunerChannels()
{
- if(mTunerChannel == null)
+ if(mTunerChannels == null && mSourceConfiguration != null)
{
- if(mSourceConfiguration.getSourceType() == SourceType.TUNER)
- {
- SourceConfigTuner config = (SourceConfigTuner)mSourceConfiguration;
+ mTunerChannels = new ArrayList<>();
- mTunerChannel = new TunerChannel(config.getFrequency(),
- mDecodeConfiguration.getChannelSpecification().getBandwidth());
- }
- else if(mSourceConfiguration.getSourceType() == SourceType.RECORDING)
+ switch(mSourceConfiguration.getSourceType())
{
- SourceConfigRecording config = (SourceConfigRecording)mSourceConfiguration;
-
- mTunerChannel = new TunerChannel(config.getFrequency(),
- mDecodeConfiguration.getChannelSpecification().getBandwidth());
+ case TUNER:
+ if(mSourceConfiguration instanceof SourceConfigTuner tunerConfig)
+ {
+ mTunerChannels.add(new TunerChannel(tunerConfig.getFrequency(),
+ mDecodeConfiguration.getChannelSpecification().getBandwidth()));
+ }
+ break;
+ case TUNER_MULTIPLE_FREQUENCIES:
+ if(mSourceConfiguration instanceof SourceConfigTunerMultipleFrequency multiConfig)
+ {
+ for(long frequency: multiConfig.getFrequencies())
+ {
+ mTunerChannels.add(new TunerChannel(frequency,
+ mDecodeConfiguration.getChannelSpecification().getBandwidth()));
+ }
+ }
+ break;
+ case RECORDING:
+ if(mSourceConfiguration instanceof SourceConfigRecording recordingConfig)
+ {
+ mTunerChannels.add(new TunerChannel(recordingConfig.getFrequency(),
+ mDecodeConfiguration.getChannelSpecification().getBandwidth()));
+ }
+ break;
+ default:
+ mLog.warn("Unrecognized channel source type: " + mSourceConfiguration.getSourceType());
}
}
- return mTunerChannel;
+ return mTunerChannels;
}
/**
@@ -717,9 +728,15 @@ else if(mSourceConfiguration.getSourceType() == SourceType.RECORDING)
*/
public boolean isWithin(long minimum, long maximum)
{
- TunerChannel tunerChannel = getTunerChannel();
+ for(TunerChannel tunerChannel: getTunerChannels())
+ {
+ if(tunerChannel.overlaps(minimum, maximum))
+ {
+ return true;
+ }
+ }
- return tunerChannel != null && tunerChannel.overlaps(minimum, maximum);
+ return false;
}
/**
diff --git a/src/main/java/io/github/dsheirer/gui/power/ChannelPowerPanel.java b/src/main/java/io/github/dsheirer/gui/power/ChannelPowerPanel.java
index d9abbeb28..23e41e5fe 100644
--- a/src/main/java/io/github/dsheirer/gui/power/ChannelPowerPanel.java
+++ b/src/main/java/io/github/dsheirer/gui/power/ChannelPowerPanel.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -444,11 +444,11 @@ public void receive(ProcessingChain processingChain)
if(channel != null)
{
- TunerChannel tunerChannel = channel.getTunerChannel();
+ List tunerChannels = channel.getTunerChannels();
- if(tunerChannel != null)
+ if(!tunerChannels.isEmpty())
{
- mFrequencyOverlayPanel.setChannelBandwidth(tunerChannel.getBandwidth());
+ mFrequencyOverlayPanel.setChannelBandwidth(tunerChannels.get(0).getBandwidth());
}
}
}
diff --git a/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java b/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java
index 5a462892a..b9e4d71c5 100644
--- a/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java
+++ b/src/main/java/io/github/dsheirer/spectrum/OverlayPanel.java
@@ -1,6 +1,6 @@
/*
* *****************************************************************************
- * Copyright (C) 2014-2023 Dennis Sheirer
+ * Copyright (C) 2014-2024 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
@@ -550,60 +550,63 @@ else if(channel.isProcessing())
graphics.setColor(mColorChannelConfig);
}
- TunerChannel tunerChannel = channel.getTunerChannel();
+ List tunerChannels = channel.getTunerChannels();
- if(tunerChannel != null)
+ for(TunerChannel tunerChannel: tunerChannels)
{
- double xAxis = getAxisFromFrequency(tunerChannel.getFrequency());
+ if(tunerChannel.overlaps(getMinDisplayFrequency(), getMaxDisplayFrequency()))
+ {
+ double xAxis = getAxisFromFrequency(tunerChannel.getFrequency());
- double width = (double)(tunerChannel.getBandwidth()) / (double)getDisplayBandwidth() * getSize().getWidth();
+ double width = (double)(tunerChannel.getBandwidth()) / (double)getDisplayBandwidth() * getSize().getWidth();
- Rectangle2D.Double box =
- new Rectangle2D.Double(xAxis - (width / 2.0d), 0.0d, width, getSize().getHeight() - mSpectrumInset);
+ Rectangle2D.Double box =
+ new Rectangle2D.Double(xAxis - (width / 2.0d), 0.0d, width, getSize().getHeight() - mSpectrumInset);
- //Fill the box with the correct color
- graphics.fill(box);
+ //Fill the box with the correct color
+ graphics.fill(box);
- graphics.draw(box);
+ graphics.draw(box);
- //Change to the line color to render the channel name, etc.
- graphics.setColor(mColorSpectrumLine);
+ //Change to the line color to render the channel name, etc.
+ graphics.setColor(mColorSpectrumLine);
- //Draw the labels starting at yAxis position 0
- double yAxis = 0;
+ //Draw the labels starting at yAxis position 0
+ double yAxis = 0;
- //Draw the system label and adjust the y-axis position
- String system = channel.hasSystem() ? channel.getSystem() : " ";
+ //Draw the system label and adjust the y-axis position
+ String system = channel.hasSystem() ? channel.getSystem() : " ";
- yAxis += drawLabel(graphics, system, this.getFont(), xAxis, yAxis, width);
+ yAxis += drawLabel(graphics, system, this.getFont(), xAxis, yAxis, width);
- //Draw the site label and adjust the y-axis position
- String site = channel.hasSite() ? channel.getSite() : " ";
+ //Draw the site label and adjust the y-axis position
+ String site = channel.hasSite() ? channel.getSite() : " ";
- yAxis += drawLabel(graphics, site, this.getFont(), xAxis, yAxis, width);
+ yAxis += drawLabel(graphics, site, this.getFont(), xAxis, yAxis, width);
- //Draw the channel label and adjust the y-axis position
- yAxis += drawLabel(graphics, channel.getName(), this.getFont(), xAxis, yAxis, width);
+ //Draw the channel label and adjust the y-axis position
+ yAxis += drawLabel(graphics, channel.getName(), this.getFont(), xAxis, yAxis, width);
- //Draw the decoder label
- drawLabel(graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
- this.getFont(), xAxis, yAxis, width);
+ //Draw the decoder label
+ drawLabel(graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
+ this.getFont(), xAxis, yAxis, width);
- long frequency = tunerChannel.getFrequency();
+ long frequency = tunerChannel.getFrequency();
- double frequencyAxis = getAxisFromFrequency(frequency);
+ double frequencyAxis = getAxisFromFrequency(frequency);
- drawChannelCenterLine(graphics, frequencyAxis);
-
- /* Draw Automatic Frequency Control line */
- int correction = channel.getChannelFrequencyCorrection();
+ drawChannelCenterLine(graphics, frequencyAxis);
- if(correction != 0)
- {
- long error = frequency + correction;
+ /* Draw Automatic Frequency Control line */
+ int correction = channel.getChannelFrequencyCorrection();
+
+ if(correction != 0)
+ {
+ long error = frequency + correction;
- drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error), width, correction,
- tunerChannel.getFrequency());
+ drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error), width, correction,
+ tunerChannel.getFrequency());
+ }
}
}
}
@@ -796,11 +799,14 @@ public ArrayList getChannelsAtFrequency(long frequency)
for(Channel config : mVisibleChannels)
{
- TunerChannel channel = config.getTunerChannel();
+ List channels = config.getTunerChannels();
- if(channel != null && channel.getMinFrequency() <= frequency && channel.getMaxFrequency() >= frequency)
+ for(TunerChannel channel: channels)
{
- configs.add(config);
+ if(channel != null && channel.getMinFrequency() <= frequency && channel.getMaxFrequency() >= frequency)
+ {
+ configs.add(config);
+ }
}
}