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); + } } }