mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 17:47:32 -05:00
#1847 Updates spectral display to show channel overlay for all frequencies in a channel configuration that contains multiple frequencies. (#1848)
Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -1,23 +1,20 @@
|
|||||||
/*
|
/*
|
||||||
|
* *****************************************************************************
|
||||||
|
* Copyright (C) 2014-2024 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* * ******************************************************************************
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
* it under the terms of the GNU General Public License as published by
|
||||||
* *
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* * This program is free software: you can redistribute it and/or modify
|
* (at your option) any later version.
|
||||||
* * it under the terms of the GNU General Public License as published by
|
|
||||||
* * the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* * (at your option) any later version.
|
|
||||||
* *
|
|
||||||
* * This program is distributed in the hope that it will be useful,
|
|
||||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* * GNU General Public License for more details.
|
|
||||||
* *
|
|
||||||
* * You should have received a copy of the GNU General Public License
|
|
||||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
* * *****************************************************************************
|
|
||||||
*
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
package io.github.dsheirer.controller.channel;
|
package io.github.dsheirer.controller.channel;
|
||||||
|
|
||||||
@@ -35,13 +32,16 @@ import io.github.dsheirer.record.RecorderType;
|
|||||||
import io.github.dsheirer.record.config.RecordConfiguration;
|
import io.github.dsheirer.record.config.RecordConfiguration;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.source.SourceEvent;
|
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.SourceConfigFactory;
|
||||||
import io.github.dsheirer.source.config.SourceConfigRecording;
|
import io.github.dsheirer.source.config.SourceConfigRecording;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTuner;
|
import io.github.dsheirer.source.config.SourceConfigTuner;
|
||||||
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency;
|
||||||
import io.github.dsheirer.source.config.SourceConfiguration;
|
import io.github.dsheirer.source.config.SourceConfiguration;
|
||||||
import io.github.dsheirer.source.tuner.channel.TunerChannel;
|
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.Observable;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.IntegerProperty;
|
import javafx.beans.property.IntegerProperty;
|
||||||
@@ -55,9 +55,6 @@ import javafx.util.Callback;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.beans.Transient;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@JacksonXmlRootElement(localName = "channel")
|
@JacksonXmlRootElement(localName = "channel")
|
||||||
public class Channel extends Configuration implements Listener<SourceEvent>
|
public class Channel extends Configuration implements Listener<SourceEvent>
|
||||||
{
|
{
|
||||||
@@ -88,7 +85,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
|
|||||||
private BooleanProperty mAutoStart = new SimpleBooleanProperty();
|
private BooleanProperty mAutoStart = new SimpleBooleanProperty();
|
||||||
private IntegerProperty mAutoStartOrder = new SimpleIntegerProperty();
|
private IntegerProperty mAutoStartOrder = new SimpleIntegerProperty();
|
||||||
private boolean mSelected;
|
private boolean mSelected;
|
||||||
private TunerChannel mTunerChannel = null;
|
private List<TunerChannel> mTunerChannels = null;
|
||||||
|
|
||||||
private ChannelType mChannelType = ChannelType.STANDARD;
|
private ChannelType mChannelType = ChannelType.STANDARD;
|
||||||
|
|
||||||
@@ -634,9 +631,8 @@ public class Channel extends Configuration implements Listener<SourceEvent>
|
|||||||
|
|
||||||
updateFrequencies();
|
updateFrequencies();
|
||||||
|
|
||||||
//Clear the tune channel object so that it can be recreated if the
|
//Clear the tune channels object so that it can be recreated if the source configuration changes
|
||||||
//source configuration changes
|
mTunerChannels = null;
|
||||||
mTunerChannel = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -680,35 +676,50 @@ public class Channel extends Configuration implements Listener<SourceEvent>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to construct a tuner channel object representing a
|
* Convenience method to construct a tuner channel object representing a tuner or recording source frequency and
|
||||||
* tuner or recording source frequency and bandwidth that can be used by
|
* bandwidth that can be used by application components for graphically representing this channel.
|
||||||
* application components for graphically representing this channel.
|
|
||||||
*
|
*
|
||||||
* If the source configuration is not a tuner or recording, this method
|
* If the source configuration is not a tuner or recording, this method returns an empty list.
|
||||||
* returns null.
|
|
||||||
*/
|
*/
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public TunerChannel getTunerChannel()
|
public List<TunerChannel> getTunerChannels()
|
||||||
{
|
{
|
||||||
if(mTunerChannel == null)
|
if(mTunerChannels == null && mSourceConfiguration != null)
|
||||||
{
|
{
|
||||||
if(mSourceConfiguration.getSourceType() == SourceType.TUNER)
|
mTunerChannels = new ArrayList<>();
|
||||||
{
|
|
||||||
SourceConfigTuner config = (SourceConfigTuner)mSourceConfiguration;
|
|
||||||
|
|
||||||
mTunerChannel = new TunerChannel(config.getFrequency(),
|
switch(mSourceConfiguration.getSourceType())
|
||||||
mDecodeConfiguration.getChannelSpecification().getBandwidth());
|
|
||||||
}
|
|
||||||
else if(mSourceConfiguration.getSourceType() == SourceType.RECORDING)
|
|
||||||
{
|
{
|
||||||
SourceConfigRecording config = (SourceConfigRecording)mSourceConfiguration;
|
case TUNER:
|
||||||
|
if(mSourceConfiguration instanceof SourceConfigTuner tunerConfig)
|
||||||
mTunerChannel = new TunerChannel(config.getFrequency(),
|
{
|
||||||
mDecodeConfiguration.getChannelSpecification().getBandwidth());
|
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 @@ public class Channel extends Configuration implements Listener<SourceEvent>
|
|||||||
*/
|
*/
|
||||||
public boolean isWithin(long minimum, long maximum)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -444,11 +444,11 @@ public class ChannelPowerPanel extends JPanel implements Listener<ProcessingChai
|
|||||||
|
|
||||||
if(channel != null)
|
if(channel != null)
|
||||||
{
|
{
|
||||||
TunerChannel tunerChannel = channel.getTunerChannel();
|
List<TunerChannel> tunerChannels = channel.getTunerChannels();
|
||||||
|
|
||||||
if(tunerChannel != null)
|
if(!tunerChannels.isEmpty())
|
||||||
{
|
{
|
||||||
mFrequencyOverlayPanel.setChannelBandwidth(tunerChannel.getBandwidth());
|
mFrequencyOverlayPanel.setChannelBandwidth(tunerChannels.get(0).getBandwidth());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -550,60 +550,63 @@ public class OverlayPanel extends JPanel implements Listener<ChannelEvent>, ISou
|
|||||||
graphics.setColor(mColorChannelConfig);
|
graphics.setColor(mColorChannelConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
TunerChannel tunerChannel = channel.getTunerChannel();
|
List<TunerChannel> tunerChannels = channel.getTunerChannels();
|
||||||
|
|
||||||
if(tunerChannel != null)
|
for(TunerChannel tunerChannel: tunerChannels)
|
||||||
{
|
{
|
||||||
double xAxis = getAxisFromFrequency(tunerChannel.getFrequency());
|
if(tunerChannel.overlaps(getMinDisplayFrequency(), getMaxDisplayFrequency()))
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
//Fill the box with the correct color
|
|
||||||
graphics.fill(box);
|
|
||||||
|
|
||||||
graphics.draw(box);
|
|
||||||
|
|
||||||
//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 system label and adjust the y-axis position
|
|
||||||
String system = channel.hasSystem() ? channel.getSystem() : " ";
|
|
||||||
|
|
||||||
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() : " ";
|
|
||||||
|
|
||||||
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 decoder label
|
|
||||||
drawLabel(graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
|
|
||||||
this.getFont(), xAxis, yAxis, width);
|
|
||||||
|
|
||||||
long frequency = tunerChannel.getFrequency();
|
|
||||||
|
|
||||||
double frequencyAxis = getAxisFromFrequency(frequency);
|
|
||||||
|
|
||||||
drawChannelCenterLine(graphics, frequencyAxis);
|
|
||||||
|
|
||||||
/* Draw Automatic Frequency Control line */
|
|
||||||
int correction = channel.getChannelFrequencyCorrection();
|
|
||||||
|
|
||||||
if(correction != 0)
|
|
||||||
{
|
{
|
||||||
long error = frequency + correction;
|
double xAxis = getAxisFromFrequency(tunerChannel.getFrequency());
|
||||||
|
|
||||||
drawAFC(graphics, frequencyAxis, getAxisFromFrequency(error), width, correction,
|
double width = (double)(tunerChannel.getBandwidth()) / (double)getDisplayBandwidth() * getSize().getWidth();
|
||||||
tunerChannel.getFrequency());
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
graphics.draw(box);
|
||||||
|
|
||||||
|
//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 system label and adjust the y-axis position
|
||||||
|
String system = channel.hasSystem() ? channel.getSystem() : " ";
|
||||||
|
|
||||||
|
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() : " ";
|
||||||
|
|
||||||
|
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 decoder label
|
||||||
|
drawLabel(graphics, channel.getDecodeConfiguration().getDecoderType().getShortDisplayString(),
|
||||||
|
this.getFont(), xAxis, yAxis, width);
|
||||||
|
|
||||||
|
long frequency = tunerChannel.getFrequency();
|
||||||
|
|
||||||
|
double frequencyAxis = getAxisFromFrequency(frequency);
|
||||||
|
|
||||||
|
drawChannelCenterLine(graphics, frequencyAxis);
|
||||||
|
|
||||||
|
/* 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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -796,11 +799,14 @@ public class OverlayPanel extends JPanel implements Listener<ChannelEvent>, ISou
|
|||||||
|
|
||||||
for(Channel config : mVisibleChannels)
|
for(Channel config : mVisibleChannels)
|
||||||
{
|
{
|
||||||
TunerChannel channel = config.getTunerChannel();
|
List<TunerChannel> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user