mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Updates complex decimation filters to use either scalar or vector optimal implementation. (#1148)
Updates HackRF native byte buffers with automatic DC removal. Creates new half-band channel source to replace the cic-based channel source in the heterodyne channelizer. Resolves issue in RTL native buffer processing. Creates a CACHED thread pool and reduces the number of threads for the SCHEDULED thread pool to 2. Changes each of the channel source implementations to use a dedicated thread (Dispatcher class) instead of the scheduled thread pool, to reduce the amount of buffered/retained samples objects in memory. Lots of other small changes and tweaks. Removes last of Reusable buffer code. Updates DFTProcessor to use a single thread scheduled executor. Updates Polyphase channelizer to use threads instead of an executor. Removes a number of unused classes. Commenting out window calibration. Scalar is faster in both implementations. Adds vector and scalar implementations for windows. Repackages window and window type classes. WIP adds vector implementations for Airspy non-interleaved buffer iterator and calibration plugins for both interleaved and non-interleaved buffer iterators. WIP adds vector implementations for Airspy interleaved buffer iterator. Work on developing scalar and vector implementations of airspy sample conversion and airspy native buffer processing. Introduces new INativeBuffer framework where tuner raw samples are retained in their native (compressed) format until when they're needed and they are converted on-demand into smaller complex sample buffers to aid garbage collection. Removes all usage of ReusableComplexBuffers and ReusableChannelREsultsBuffers. Updates polyphase channelizer to be more efficient in output channel processing. Updates ViterbiDecoder to change Map usage to array for memory efficiency. Updates channel processors to used scalar implementation for gain and mixer, until the polyphase channel results can be fixed to be a multiple of the SIMD lane width. Resolves final changes for the conversion from interleaved sample arrays to complexsamples buffers for distributing baseband samples to channels and processing chains. Updates tuner channel sources and all decoders to receive new complex samples buffers, removing the previous reusable complex buffers as the default baseband samples buffer object. Still to resolve is the ComplexMixer implementations. Needs validation and a calibration implementation with an update to the complex mixer factory. Updates the DMR decoder to use optimal (scalar vs vector) implementations of filter and AGC controls. Updates the AM demodulator for separated I&Q float sample processing. Code review and testing changes. updates build script for runtime configuration. Integrates calibration manager with main sdrtrunk application. Updates NBFMDecoder to use new optimized FIR and Decimation filter options. Updates real half-band decimation filters to select the optimal (scalar vs vector) implementation. Adds calibration manager plugins. Adds calibration manager and plugins to determine the optimal (scalar vs vector) implementation type to use for various classes of dsp components. Adds vector squelching FM demodulator and cleans up the IIR filter and power squelch to use all floats. Adds vector implementation of FM demodulator. This introduces a new interface that accepts i/q samples as two separate float arrays, versus an interleaved array, which enables more efficient processing. This new complex sample interface will be used across the codebase eventually. Adds ComplexOscillator and a SIMD version VectorComplexOscillator. Deprecates the LowPhaseNoiseOscillator because the ComplexOscillator is about 35% faster. The vectorized version is about 43% faster when SIMD lane width is 8x. Adds new vector complex filters and new real oscillators. Note: the RealOscillator using straight Java math sin() function is 3x slower than the existing legacy implementation. Will replace this with a complex oscillator that only uses the real part. Updates ComplexFIRFilter to be 50% more efficient. Adds 23 tap filter implementations. Will not add 63-tap implementations because they are slower than the default vector implementation. Adds 15-tap customized vector half band filters. Adds initial custom complex vector half-band decimation filters for 11-tap and 15-tap decimation filters.. Adds vector complex half band filter implementations. Note: performance of the generic 64-bit 2-lane filter is horrible and is not included. Optimizes complex half-band filter to be 27% more efficient. Implements vectorized real half-band filter implementations. Implements a new FIR filter class that processes sample buffers instead of single sample at a time. Refactored all of the calibratons to be time-duration based. Testing on windows i7 gen 3 CPU showed that it took 1000x longer for one of the calibrations to run, versus my AMD 5800x. Changed gradle jvm args so that the windows plaf export is always applied. Updates gradle build script to ensure incubator module is included and to cleanup javafx library management for building runtime images. Testing tweaks and changes. Adds logging limiter to dispatcher for buffer overflows Adds User Preferences editor for performing Vector/SIMD calibrations and new startup dialog prompting the user to perform calibrations. Updates calibration manager and all calibration implementations to add warm-up and test phases and to reduce the overall time it takes to calibrate a system. Co-authored-by: Dennis Sheirer <dsheirer@github.com>
This commit is contained in:
@@ -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;
|
||||
@@ -37,6 +34,7 @@ import io.github.dsheirer.gui.playlist.channelMap.ViewChannelMapEditorRequest;
|
||||
import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
||||
import io.github.dsheirer.gui.preference.UserPreferencesEditor;
|
||||
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||
import io.github.dsheirer.gui.preference.calibration.CalibrationDialog;
|
||||
import io.github.dsheirer.icon.IconModel;
|
||||
import io.github.dsheirer.jmbe.JmbeEditor;
|
||||
import io.github.dsheirer.jmbe.JmbeEditorRequest;
|
||||
@@ -68,6 +66,7 @@ public class JavaFxWindowManager extends Application
|
||||
public static final String ICON_MANAGER = "iconmanager";
|
||||
public static final String PLAYLIST_EDITOR = "playlist";
|
||||
public static final String USER_PREFERENCES_EDITOR = "preferences";
|
||||
public static final String STAGE_MONITOR_KEY_CALIBRATION_DIALOG = "calibration.dialog";
|
||||
public static final String STAGE_MONITOR_KEY_CHANNEL_MAP_EDITOR = "channel.map";
|
||||
public static final String STAGE_MONITOR_KEY_ICON_MANAGER_EDITOR = "icon.manager";
|
||||
public static final String STAGE_MONITOR_KEY_JMBE_EDITOR = "jmbe.editor";
|
||||
@@ -187,6 +186,12 @@ public class JavaFxWindowManager extends Application
|
||||
Platform.exit();
|
||||
}
|
||||
|
||||
public CalibrationDialog getCalibrationDialog(UserPreferences userPreferences)
|
||||
{
|
||||
createJFXPanel();
|
||||
return new CalibrationDialog(userPreferences);
|
||||
}
|
||||
|
||||
public Stage getIconManagerStage()
|
||||
{
|
||||
if(mIconManagerStage == null)
|
||||
|
||||
@@ -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
|
||||
@@ -33,7 +33,10 @@ import io.github.dsheirer.controller.channel.ChannelSelectionManager;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.gui.icon.ViewIconManagerRequest;
|
||||
import io.github.dsheirer.gui.playlist.ViewPlaylistRequest;
|
||||
import io.github.dsheirer.gui.preference.CalibrateRequest;
|
||||
import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
||||
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
|
||||
import io.github.dsheirer.gui.preference.calibration.CalibrationDialog;
|
||||
import io.github.dsheirer.icon.IconModel;
|
||||
import io.github.dsheirer.log.ApplicationLog;
|
||||
import io.github.dsheirer.map.MapService;
|
||||
@@ -55,6 +58,9 @@ import io.github.dsheirer.spectrum.ShowTunerMenuItem;
|
||||
import io.github.dsheirer.spectrum.SpectralDisplayPanel;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import io.github.dsheirer.util.TimeStamp;
|
||||
import io.github.dsheirer.vector.calibrate.CalibrationManager;
|
||||
import javafx.application.Platform;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
import jiconfont.swing.IconFontSwing;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
@@ -62,24 +68,11 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
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.*;
|
||||
import javax.swing.event.MenuEvent;
|
||||
import javax.swing.event.MenuListener;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import java.awt.AWTException;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Point;
|
||||
import java.awt.Robot;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
@@ -92,6 +85,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
public class SDRTrunk implements Listener<TunerEvent>
|
||||
{
|
||||
@@ -170,6 +164,11 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||
mPlaylistManager = new PlaylistManager(mUserPreferences, mSourceManager, aliasModel, eventLogManager, mIconModel);
|
||||
mJavaFxWindowManager = new JavaFxWindowManager(mUserPreferences, mPlaylistManager);
|
||||
|
||||
CalibrationManager calibrationManager = CalibrationManager.getInstance(mUserPreferences);
|
||||
final boolean calibrating = !calibrationManager.isCalibrated() &&
|
||||
!mUserPreferences.getVectorCalibrationPreference().isHideCalibrationDialog();
|
||||
|
||||
new ChannelSelectionManager(mPlaylistManager.getChannelModel());
|
||||
|
||||
AudioPlaybackManager audioPlaybackManager = new AudioPlaybackManager(mUserPreferences);
|
||||
@@ -215,7 +214,29 @@ public class SDRTrunk implements Listener<TunerEvent>
|
||||
try
|
||||
{
|
||||
mMainGui.setVisible(true);
|
||||
autoStartChannels();
|
||||
|
||||
if(calibrating)
|
||||
{
|
||||
Platform.runLater(() ->
|
||||
{
|
||||
CalibrationDialog calibrationDialog = mJavaFxWindowManager.getCalibrationDialog(mUserPreferences);
|
||||
Optional<ButtonType> calibrate = calibrationDialog.showAndWait();
|
||||
if(calibrate.isPresent() && calibrate.get().getText().equals("Calibrate"))
|
||||
{
|
||||
//Request focus and execute calibration
|
||||
MyEventBus.getGlobalEventBus().post(new ViewUserPreferenceEditorRequest(PreferenceEditorType.VECTOR_CALIBRATION));
|
||||
MyEventBus.getGlobalEventBus().post(new CalibrateRequest());
|
||||
}
|
||||
else
|
||||
{
|
||||
autoStartChannels();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
autoStartChannels();
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
@@ -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,14 +14,15 @@
|
||||
*
|
||||
* 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.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.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
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;
|
||||
@@ -32,7 +32,7 @@ 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.DFTProcessor;
|
||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||
import io.github.dsheirer.spectrum.converter.ComplexDecibelConverter;
|
||||
@@ -40,16 +40,10 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
@@ -85,8 +79,6 @@ public class ChannelizerViewer extends JFrame
|
||||
public ChannelizerViewer(int channelsPerRow)
|
||||
{
|
||||
mTestTuner = new TestTuner(new UserPreferences());
|
||||
|
||||
// mChannelCount = (int)(mTestTuner.getTunerController().getUsableBandwidth() / CHANNEL_BANDWIDTH);
|
||||
mChannelCount = (int)(mTestTuner.getTunerController().getBandwidth() / CHANNEL_BANDWIDTH);
|
||||
mChannelsPerRow = channelsPerRow;
|
||||
|
||||
@@ -310,9 +302,9 @@ public class ChannelizerViewer extends JFrame
|
||||
return tunerChannels;
|
||||
}
|
||||
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<ReusableComplexBuffer>, ISourceEventProcessor
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<INativeBuffer>, ISourceEventProcessor
|
||||
{
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
|
||||
@@ -323,20 +315,19 @@ public class ChannelizerViewer extends JFrame
|
||||
mSpectrumPanel.setSampleSize(28);
|
||||
add(mSpectrumPanel);
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -346,10 +337,10 @@ public class ChannelizerViewer extends JFrame
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelPanel extends JPanel implements Listener<ReusableComplexBuffer>, ISourceEventProcessor
|
||||
public class ChannelPanel extends JPanel implements Listener<ComplexSamples>, ISourceEventProcessor
|
||||
{
|
||||
private TunerChannelSource mSource;
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private JToggleButton mLoggingButton;
|
||||
@@ -362,8 +353,7 @@ public class ChannelizerViewer extends JFrame
|
||||
mSpectrumPanel.setSampleSize(32);
|
||||
add(mSpectrumPanel, "span");
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
TunerChannel tunerChannel = new TunerChannel(frequency, bandwidth);
|
||||
@@ -371,21 +361,7 @@ public class ChannelizerViewer extends JFrame
|
||||
|
||||
if(mSource != null)
|
||||
{
|
||||
mSource.setListener(new Listener<ReusableComplexBuffer>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
{
|
||||
if(mLoggingEnabled)
|
||||
{
|
||||
mLog.debug("Samples:" + Arrays.toString(complexBuffer.getSamples()));
|
||||
}
|
||||
|
||||
complexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(complexBuffer);
|
||||
complexBuffer.decrementUserCount();
|
||||
}
|
||||
});
|
||||
mSource.setListener(complexSamples -> mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved())));
|
||||
|
||||
mSource.start();
|
||||
}
|
||||
@@ -423,15 +399,13 @@ public class ChannelizerViewer extends JFrame
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
reusableComplexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
reusableComplexBuffer.decrementUserCount();
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -441,12 +415,12 @@ public class ChannelizerViewer extends JFrame
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscreteChannelPanel extends JPanel implements Listener<ReusableComplexBuffer>, ISourceEventProcessor
|
||||
public class DiscreteChannelPanel extends JPanel implements Listener<ComplexSamples>, ISourceEventProcessor
|
||||
{
|
||||
private final Logger mLog = LoggerFactory.getLogger(DiscreteChannelPanel.class);
|
||||
|
||||
private TunerChannelSource mSource;
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private JToggleButton mLoggingButton;
|
||||
@@ -472,25 +446,22 @@ public class ChannelizerViewer extends JFrame
|
||||
});
|
||||
// add(mLoggingButton);
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(25000.0));
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
if(mSource != null)
|
||||
{
|
||||
mSource.setListener(new Listener<ReusableComplexBuffer>()
|
||||
mSource.setListener(new Listener<ComplexSamples>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
if(mLoggingEnabled)
|
||||
{
|
||||
mLog.debug("Samples:" + Arrays.toString(complexBuffer.getSamples()));
|
||||
mLog.debug("Samples:" + Arrays.toString(complexSamples.toInterleaved().samples()));
|
||||
}
|
||||
|
||||
complexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(complexBuffer);
|
||||
complexBuffer.decrementUserCount();
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -509,15 +480,13 @@ public class ChannelizerViewer extends JFrame
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
reusableComplexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
reusableComplexBuffer.decrementUserCount();
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -579,12 +548,11 @@ public class ChannelizerViewer extends JFrame
|
||||
|
||||
for(TunerChannelSource tunerChannelSource : sources)
|
||||
{
|
||||
tunerChannelSource.setListener(new Listener<ReusableComplexBuffer>()
|
||||
tunerChannelSource.setListener(new Listener<ComplexSamples>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
reusableComplexBuffer.decrementUserCount();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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,14 +14,15 @@
|
||||
*
|
||||
* 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.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.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
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;
|
||||
@@ -33,7 +33,7 @@ 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.DFTProcessor;
|
||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||
import io.github.dsheirer.spectrum.converter.ComplexDecibelConverter;
|
||||
@@ -41,22 +41,13 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ChannelizerViewer2 extends JFrame
|
||||
@@ -325,9 +316,9 @@ public class ChannelizerViewer2 extends JFrame
|
||||
return tunerChannels;
|
||||
}
|
||||
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<ReusableComplexBuffer>, ISourceEventProcessor
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<INativeBuffer>, ISourceEventProcessor
|
||||
{
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
|
||||
@@ -338,20 +329,19 @@ public class ChannelizerViewer2 extends JFrame
|
||||
mSpectrumPanel.setSampleSize(16);
|
||||
add(mSpectrumPanel);
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -361,10 +351,10 @@ public class ChannelizerViewer2 extends JFrame
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelPanel extends JPanel implements Listener<ReusableComplexBuffer>, ISourceEventProcessor
|
||||
public class ChannelPanel extends JPanel implements Listener<INativeBuffer>, ISourceEventProcessor
|
||||
{
|
||||
private TunerChannelSource mSource;
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private JToggleButton mLoggingButton;
|
||||
@@ -377,8 +367,7 @@ public class ChannelizerViewer2 extends JFrame
|
||||
mSpectrumPanel.setSampleSize(16);
|
||||
add(mSpectrumPanel, "span");
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(sampleRate));
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
TunerChannel tunerChannel = new TunerChannel(frequency, bandwidth);
|
||||
@@ -387,20 +376,9 @@ public class ChannelizerViewer2 extends JFrame
|
||||
if(mSource != null)
|
||||
{
|
||||
mLog.debug("Channel: " + mSource.getTunerChannel() + " Rate:" + mSource.getSampleRate());
|
||||
mSource.setListener(new Listener<ReusableComplexBuffer>()
|
||||
mSource.setListener((Listener<ComplexSamples>) complexSamples ->
|
||||
{
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
{
|
||||
if(mLoggingEnabled)
|
||||
{
|
||||
mLog.debug("Samples:" + Arrays.toString(complexBuffer.getSamples()));
|
||||
}
|
||||
|
||||
complexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(complexBuffer);
|
||||
complexBuffer.decrementUserCount();
|
||||
}
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
});
|
||||
|
||||
mSource.start();
|
||||
@@ -423,14 +401,7 @@ public class ChannelizerViewer2 extends JFrame
|
||||
}
|
||||
|
||||
mLoggingButton = new JToggleButton("Logging");
|
||||
mLoggingButton.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
mLoggingEnabled = mLoggingButton.isSelected();
|
||||
}
|
||||
});
|
||||
mLoggingButton.addActionListener(e -> mLoggingEnabled = mLoggingButton.isSelected());
|
||||
}
|
||||
|
||||
public TunerChannelSource getSource()
|
||||
@@ -440,15 +411,13 @@ public class ChannelizerViewer2 extends JFrame
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
reusableComplexBuffer.incrementUserCount();
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
reusableComplexBuffer.decrementUserCount();
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.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.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;
|
||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||
import io.github.dsheirer.spectrum.converter.ComplexDecibelConverter;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class HeterodyneChannelizerViewer extends JFrame
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(HeterodyneChannelizerViewer.class);
|
||||
|
||||
private static final int CHANNEL_BANDWIDTH = 12500;
|
||||
private static final int CHANNEL_FFT_FRAME_RATE = 20;
|
||||
|
||||
private SettingsManager mSettingsManager = new SettingsManager(new TunerConfigurationModel());
|
||||
private JPanel mPrimaryPanel;
|
||||
private JPanel mControlPanel;
|
||||
private JLabel mToneFrequencyLabel;
|
||||
private PrimarySpectrumPanel mPrimarySpectrumPanel;
|
||||
private ChannelArrayPanel mChannelPanel;
|
||||
private DiscreteIndexChannelArrayPanel mDiscreteIndexChannelPanel;
|
||||
private int mChannelCount;
|
||||
private int mChannelsPerRow;
|
||||
private long mBaseFrequency = 100000000; //100 MHz
|
||||
private DFTSize mMainPanelDFTSize = DFTSize.FFT04096;
|
||||
private DFTSize mChannelPanelDFTSize = DFTSize.FFT04096;
|
||||
private TestTuner mTestTuner;
|
||||
|
||||
/**
|
||||
* GUI Test utility for researching channelizers.
|
||||
*/
|
||||
public HeterodyneChannelizerViewer()
|
||||
{
|
||||
mTestTuner = new TestTuner(new UserPreferences());
|
||||
mChannelCount = 5;
|
||||
mChannelsPerRow = 5;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setTitle("Heterodyne Channelizer Viewer");
|
||||
setSize(1200, 800);
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||
setLocationRelativeTo(null);
|
||||
add(getPrimaryPanel());
|
||||
}
|
||||
|
||||
private JPanel getPrimaryPanel()
|
||||
{
|
||||
if(mPrimaryPanel == null)
|
||||
{
|
||||
mPrimaryPanel = new JPanel();
|
||||
mPrimaryPanel.setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[][][grow,fill][grow,fill]"));
|
||||
mPrimaryPanel.add(getSpectrumPanel(), "wrap");
|
||||
mPrimaryPanel.add(getControlPanel(), "wrap");
|
||||
mPrimaryPanel.add(getChannelArrayPanel(), "wrap");
|
||||
// mPrimaryPanel.add(getDiscreteIndexChannelPanel());
|
||||
}
|
||||
|
||||
return mPrimaryPanel;
|
||||
}
|
||||
|
||||
private PrimarySpectrumPanel getSpectrumPanel()
|
||||
{
|
||||
if(mPrimarySpectrumPanel == null)
|
||||
{
|
||||
mPrimarySpectrumPanel = new PrimarySpectrumPanel(mSettingsManager,
|
||||
mTestTuner.getTunerController().getSampleRate());
|
||||
mPrimarySpectrumPanel.setPreferredSize(new Dimension(1200, 200));
|
||||
mPrimarySpectrumPanel.setDFTSize(mMainPanelDFTSize);
|
||||
mTestTuner.getTunerController().addBufferListener(mPrimarySpectrumPanel);
|
||||
}
|
||||
|
||||
return mPrimarySpectrumPanel;
|
||||
}
|
||||
|
||||
private JPanel getControlPanel()
|
||||
{
|
||||
if(mControlPanel == null)
|
||||
{
|
||||
mControlPanel = new JPanel();
|
||||
mControlPanel.setLayout(new MigLayout("insets 0 0 0 0", "", ""));
|
||||
|
||||
mControlPanel.add(new JLabel("Tone:"), "align left");
|
||||
long minimumFrequency = -(long)mTestTuner.getTunerController().getSampleRate() / 2 + 1;
|
||||
long maximumFrequency = (long)mTestTuner.getTunerController().getSampleRate() / 2 - 1;
|
||||
long toneFrequency = 0;
|
||||
|
||||
SpinnerNumberModel model = new SpinnerNumberModel(toneFrequency, minimumFrequency, maximumFrequency,
|
||||
100);
|
||||
|
||||
model.addChangeListener(new ChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e)
|
||||
{
|
||||
long toneFrequency = model.getNumber().longValue();
|
||||
mTestTuner.getTunerController().setToneFrequency(toneFrequency);
|
||||
mToneFrequencyLabel.setText(String.valueOf(getToneFrequency()));
|
||||
}
|
||||
});
|
||||
|
||||
JSpinner spinner = new JSpinner(model);
|
||||
|
||||
mControlPanel.add(spinner);
|
||||
mControlPanel.add(new JLabel("Hz"));
|
||||
|
||||
mControlPanel.add(new JLabel("Frequency:"), "push,align right");
|
||||
mToneFrequencyLabel = new JLabel(String.valueOf(getToneFrequency()));
|
||||
mControlPanel.add(mToneFrequencyLabel, "push,align left");
|
||||
|
||||
mControlPanel.add(new JLabel("Channels: " + mChannelCount), "push,align right");
|
||||
}
|
||||
|
||||
return mControlPanel;
|
||||
}
|
||||
|
||||
private long getToneFrequency()
|
||||
{
|
||||
return mTestTuner.getTunerController().getFrequency() + mTestTuner.getTunerController().getToneFrequency();
|
||||
}
|
||||
|
||||
private ChannelArrayPanel getChannelArrayPanel()
|
||||
{
|
||||
if(mChannelPanel == null)
|
||||
{
|
||||
mChannelPanel = new ChannelArrayPanel();
|
||||
}
|
||||
|
||||
return mChannelPanel;
|
||||
}
|
||||
|
||||
private DiscreteIndexChannelArrayPanel getDiscreteIndexChannelPanel()
|
||||
{
|
||||
if(mDiscreteIndexChannelPanel == null)
|
||||
{
|
||||
mDiscreteIndexChannelPanel = new DiscreteIndexChannelArrayPanel();
|
||||
}
|
||||
|
||||
return mDiscreteIndexChannelPanel;
|
||||
}
|
||||
|
||||
public class ChannelArrayPanel extends JPanel
|
||||
{
|
||||
private final Logger mLog = LoggerFactory.getLogger(ChannelArrayPanel.class);
|
||||
|
||||
public ChannelArrayPanel()
|
||||
{
|
||||
int bufferSize = CHANNEL_BANDWIDTH / CHANNEL_FFT_FRAME_RATE;
|
||||
if(bufferSize % 2 == 1)
|
||||
{
|
||||
bufferSize++;
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "fill", "fill"));
|
||||
|
||||
double spectralBandwidth = mTestTuner.getTunerController().getSampleRate();
|
||||
double halfSpectralBandwidth = spectralBandwidth / 2.0;
|
||||
|
||||
int channelToLog = -1;
|
||||
|
||||
long baseFrequency = mBaseFrequency + (CHANNEL_BANDWIDTH / 2);
|
||||
|
||||
for(int x = 0; x < mChannelCount; x++)
|
||||
{
|
||||
long frequency = baseFrequency + (x * CHANNEL_BANDWIDTH);
|
||||
|
||||
mLog.debug("Channel " + x + "/" + mChannelCount + " Frequency: " + frequency);
|
||||
|
||||
ChannelPanel channelPanel = new ChannelPanel(mSettingsManager, CHANNEL_BANDWIDTH * 2, frequency, CHANNEL_BANDWIDTH, (x == channelToLog));
|
||||
channelPanel.setDFTSize(mChannelPanelDFTSize);
|
||||
|
||||
if(x % mChannelsPerRow == mChannelsPerRow - 1)
|
||||
{
|
||||
add(channelPanel, "grow,push,wrap 2px");
|
||||
}
|
||||
else
|
||||
{
|
||||
add(channelPanel, "grow,push");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscreteIndexChannelArrayPanel extends JPanel
|
||||
{
|
||||
public DiscreteIndexChannelArrayPanel()
|
||||
{
|
||||
int bufferSize = CHANNEL_BANDWIDTH / CHANNEL_FFT_FRAME_RATE;
|
||||
if(bufferSize % 2 == 1)
|
||||
{
|
||||
bufferSize++;
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "fill", "fill"));
|
||||
|
||||
ChannelSpecification channelSpecification = new ChannelSpecification(25000.0, 12500, 6000.0, 6250.0);
|
||||
for(int x = 0; x < mChannelCount; x++)
|
||||
{
|
||||
TunerChannel tunerChannel = new TunerChannel(100000000, 12500);
|
||||
TunerChannelSource source = mTestTuner.getChannelSourceManager().getSource(tunerChannel, channelSpecification);
|
||||
DiscreteChannelPanel channelPanel = new DiscreteChannelPanel(mSettingsManager, source, x);
|
||||
channelPanel.setDFTSize(mChannelPanelDFTSize);
|
||||
|
||||
mLog.debug("Testing Channel [" + x + "] is set to [" + source.getTunerChannel().getFrequency() + "]");
|
||||
|
||||
if(x % mChannelsPerRow == mChannelsPerRow - 1)
|
||||
{
|
||||
add(channelPanel, "grow,push,wrap 2px");
|
||||
}
|
||||
else
|
||||
{
|
||||
add(channelPanel, "grow,push");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of tuner channels that will fit within the tuner's bandwidth, minus a half channel each at the
|
||||
* lower and upper ends of the spectrum.
|
||||
*
|
||||
* @param tuner to create channels for
|
||||
* @return list of contiguous channels filling the tuner bandwidth
|
||||
*/
|
||||
public static List<TunerChannel> getTunerChannels(Tuner tuner)
|
||||
{
|
||||
List<TunerChannel> tunerChannels = new ArrayList<>();
|
||||
|
||||
long baseFrequency = tuner.getTunerController().getFrequency();
|
||||
baseFrequency -= tuner.getTunerController().getSampleRate() / 2;
|
||||
baseFrequency += (CHANNEL_BANDWIDTH / 2);
|
||||
|
||||
int channelCount = (int)(tuner.getTunerController().getSampleRate() / CHANNEL_BANDWIDTH) - 1;
|
||||
|
||||
for(int x = 0; x < channelCount; x++)
|
||||
{
|
||||
long frequency = baseFrequency + (x * CHANNEL_BANDWIDTH);
|
||||
TunerChannel tunerChannel = new TunerChannel(frequency, CHANNEL_BANDWIDTH);
|
||||
tunerChannels.add(tunerChannel);
|
||||
}
|
||||
|
||||
return tunerChannels;
|
||||
}
|
||||
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<INativeBuffer>, ISourceEventProcessor
|
||||
{
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
|
||||
public PrimarySpectrumPanel(SettingsManager settingsManager, double sampleRate)
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||
mSpectrumPanel.setSampleSize(28);
|
||||
add(mSpectrumPanel);
|
||||
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(SourceEvent event) throws SourceException
|
||||
{
|
||||
mLog.debug("Source Event! Add handler support for this to channelizer viewer");
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelPanel extends JPanel implements Listener<ComplexSamples>, ISourceEventProcessor
|
||||
{
|
||||
private TunerChannelSource mSource;
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private JToggleButton mLoggingButton;
|
||||
private boolean mLoggingEnabled;
|
||||
|
||||
public ChannelPanel(SettingsManager settingsManager, double sampleRate, long frequency, int bandwidth, boolean enableLogging)
|
||||
{
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||
mSpectrumPanel.setSampleSize(32);
|
||||
add(mSpectrumPanel, "span");
|
||||
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
TunerChannel tunerChannel = new TunerChannel(frequency, bandwidth);
|
||||
ChannelSpecification channelSpecification = new ChannelSpecification(25000.0, 12500, 6000.0, 6250.0);
|
||||
mSource = mTestTuner.getChannelSourceManager().getSource(tunerChannel, channelSpecification);
|
||||
|
||||
if(mSource != null)
|
||||
{
|
||||
mSource.setListener(complexSamples -> mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved())));
|
||||
|
||||
mSource.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.error("Couldn't get a source from the tuner for frequency: " + frequency);
|
||||
}
|
||||
|
||||
if(mSource != null)
|
||||
{
|
||||
add(new JLabel("Center:" + frequency));
|
||||
}
|
||||
else
|
||||
{
|
||||
add(new JLabel("NO SRC:" + frequency));
|
||||
}
|
||||
|
||||
mLoggingButton = new JToggleButton("Logging");
|
||||
mLoggingButton.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
mLoggingEnabled = mLoggingButton.isSelected();
|
||||
}
|
||||
});
|
||||
// add(mLoggingButton);
|
||||
|
||||
}
|
||||
|
||||
public TunerChannelSource getSource()
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(SourceEvent event) throws SourceException
|
||||
{
|
||||
mLog.debug("Source Event! Add handler support for this to channelizer viewer");
|
||||
}
|
||||
}
|
||||
|
||||
public class DiscreteChannelPanel extends JPanel implements Listener<ComplexSamples>, ISourceEventProcessor
|
||||
{
|
||||
private final Logger mLog = LoggerFactory.getLogger(DiscreteChannelPanel.class);
|
||||
|
||||
private TunerChannelSource mSource;
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private JToggleButton mLoggingButton;
|
||||
private boolean mLoggingEnabled;
|
||||
|
||||
public DiscreteChannelPanel(SettingsManager settingsManager, TunerChannelSource source, int index)
|
||||
{
|
||||
mSource = source;
|
||||
setLayout(new MigLayout("insets 0 0 0 0", "[center,grow,fill][]", "[grow,fill][]"));
|
||||
mSpectrumPanel = new SpectrumPanel(settingsManager);
|
||||
mSpectrumPanel.setSampleSize(32);
|
||||
add(mSpectrumPanel, "span");
|
||||
add(new JLabel("Index:" + index));
|
||||
|
||||
mLoggingButton = new JToggleButton("Logging");
|
||||
mLoggingButton.addActionListener(new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
mLoggingEnabled = mLoggingButton.isSelected();
|
||||
}
|
||||
});
|
||||
// add(mLoggingButton);
|
||||
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
if(mSource != null)
|
||||
{
|
||||
mSource.setListener(new Listener<ComplexSamples>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
if(mLoggingEnabled)
|
||||
{
|
||||
mLog.debug("Samples:" + Arrays.toString(complexSamples.toInterleaved().samples()));
|
||||
}
|
||||
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
});
|
||||
|
||||
mSource.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.error("Couldn't get a source from the tuner for index: " + index);
|
||||
}
|
||||
}
|
||||
|
||||
public TunerChannelSource getSource()
|
||||
{
|
||||
return mSource;
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
mComplexDftProcessor.receive(new FloatNativeBuffer(complexSamples.toInterleaved()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(SourceEvent event) throws SourceException
|
||||
{
|
||||
mLog.debug("Source Event! Add handler support for this to channelizer viewer");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
boolean useGUI = true;
|
||||
|
||||
if(useGUI)
|
||||
{
|
||||
final HeterodyneChannelizerViewer frame = new HeterodyneChannelizerViewer();
|
||||
|
||||
EventQueue.invokeLater(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
frame.setVisible(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
TestTuner tuner = new TestTuner(new UserPreferences());
|
||||
|
||||
List<TunerChannel> tunerChannels = getTunerChannels(tuner);
|
||||
|
||||
List<TunerChannelSource> sources = new ArrayList<>();
|
||||
|
||||
int maxSourceCount = 30;
|
||||
int sourceCount = 0;
|
||||
for(TunerChannel tunerChannel : tunerChannels)
|
||||
{
|
||||
if(sourceCount < maxSourceCount)
|
||||
{
|
||||
TunerChannelSource source = tuner.getChannelSourceManager().getSource(tunerChannel, null);
|
||||
|
||||
if(source != null)
|
||||
{
|
||||
sources.add(source);
|
||||
sourceCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.debug("Couldn't get source for: " + tunerChannel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mLog.debug("Starting [" + sources.size() + "] tuner channel sources");
|
||||
|
||||
for(TunerChannelSource tunerChannelSource : sources)
|
||||
{
|
||||
tunerChannelSource.setListener(new Listener<ComplexSamples>()
|
||||
{
|
||||
@Override
|
||||
public void receive(ComplexSamples complexSamples)
|
||||
{
|
||||
}
|
||||
});
|
||||
|
||||
tunerChannelSource.start();
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,36 @@
|
||||
/*******************************************************************************
|
||||
* 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.channelizer;
|
||||
|
||||
import io.github.dsheirer.buffer.FloatNativeBuffer;
|
||||
import io.github.dsheirer.buffer.INativeBuffer;
|
||||
import io.github.dsheirer.dsp.filter.FilterFactory;
|
||||
import io.github.dsheirer.dsp.filter.channelizer.TwoChannelSynthesizerM2;
|
||||
import io.github.dsheirer.dsp.filter.design.FilterDesignException;
|
||||
import io.github.dsheirer.dsp.mixer.FS4DownConverter;
|
||||
import io.github.dsheirer.dsp.mixer.IOscillator;
|
||||
import io.github.dsheirer.dsp.mixer.LowPhaseNoiseOscillator;
|
||||
import io.github.dsheirer.sample.IOverflowListener;
|
||||
import io.github.dsheirer.dsp.oscillator.FS4DownConverter;
|
||||
import io.github.dsheirer.dsp.oscillator.IComplexOscillator;
|
||||
import io.github.dsheirer.dsp.oscillator.OscillatorFactory;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceEvent;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import io.github.dsheirer.spectrum.DFTProcessor;
|
||||
import io.github.dsheirer.spectrum.ComplexDftProcessor;
|
||||
import io.github.dsheirer.spectrum.DFTSize;
|
||||
import io.github.dsheirer.spectrum.SpectrumPanel;
|
||||
import io.github.dsheirer.spectrum.converter.ComplexDecibelConverter;
|
||||
@@ -38,15 +39,10 @@ import net.miginfocom.swing.MigLayout;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SynthesizerViewer extends JFrame
|
||||
@@ -141,9 +137,9 @@ public class SynthesizerViewer extends JFrame
|
||||
return mChannel2Panel;
|
||||
}
|
||||
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<ReusableComplexBuffer>
|
||||
public class PrimarySpectrumPanel extends JPanel implements Listener<INativeBuffer>
|
||||
{
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
|
||||
@@ -154,36 +150,26 @@ public class SynthesizerViewer extends JFrame
|
||||
mSpectrumPanel.setSampleSize(16);
|
||||
add(mSpectrumPanel);
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(CHANNEL_SAMPLE_RATE));
|
||||
mDFTProcessor.setFrameRate(CHANNEL_FFT_FRAME_RATE);
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDftProcessor.setFrameRate(CHANNEL_FFT_FRAME_RATE);
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
|
||||
mDFTProcessor.setOverflowListener(new IOverflowListener()
|
||||
{
|
||||
@Override
|
||||
public void sourceOverflow(boolean overflow)
|
||||
{
|
||||
mLog.debug("Buffer " + (overflow ? "overflow" : "reset"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public class ChannelPanel extends JPanel implements Listener<ReusableComplexBuffer>
|
||||
public class ChannelPanel extends JPanel implements Listener<INativeBuffer>
|
||||
{
|
||||
private DFTProcessor mDFTProcessor = new DFTProcessor(SampleType.COMPLEX);
|
||||
private ComplexDftProcessor mComplexDftProcessor = new ComplexDftProcessor();
|
||||
private ComplexDecibelConverter mComplexDecibelConverter = new ComplexDecibelConverter();
|
||||
private SpectrumPanel mSpectrumPanel;
|
||||
private boolean mLoggingEnabled = false;
|
||||
@@ -196,22 +182,21 @@ public class SynthesizerViewer extends JFrame
|
||||
add(mSpectrumPanel, "wrap");
|
||||
add(channelControlPanel);
|
||||
|
||||
mDFTProcessor.addConverter(mComplexDecibelConverter);
|
||||
mDFTProcessor.process(SourceEvent.sampleRateChange(CHANNEL_SAMPLE_RATE));
|
||||
mDFTProcessor.setFrameRate(CHANNEL_FFT_FRAME_RATE);
|
||||
mComplexDftProcessor.addConverter(mComplexDecibelConverter);
|
||||
mComplexDftProcessor.setFrameRate(CHANNEL_FFT_FRAME_RATE);
|
||||
|
||||
mComplexDecibelConverter.addListener(mSpectrumPanel);
|
||||
}
|
||||
|
||||
public void setDFTSize(DFTSize dftSize)
|
||||
{
|
||||
mDFTProcessor.setDFTSize(dftSize);
|
||||
mComplexDftProcessor.setDFTSize(dftSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mDFTProcessor.receive(reusableComplexBuffer);
|
||||
mComplexDftProcessor.receive(nativeBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,7 +226,7 @@ public class SynthesizerViewer extends JFrame
|
||||
private static final int MAX_FREQUENCY = 6250;
|
||||
private static final int DEFAULT_FREQUENCY = 50;
|
||||
|
||||
private IOscillator mOscillator = new LowPhaseNoiseOscillator(DEFAULT_FREQUENCY, CHANNEL_SAMPLE_RATE);
|
||||
private IComplexOscillator mOscillator = OscillatorFactory.getComplexOscillator(DEFAULT_FREQUENCY, CHANNEL_SAMPLE_RATE);
|
||||
|
||||
public ChannelControlPanel()
|
||||
{
|
||||
@@ -264,7 +249,7 @@ public class SynthesizerViewer extends JFrame
|
||||
add(new JLabel("Hz"));
|
||||
}
|
||||
|
||||
public IOscillator getOscillator()
|
||||
public IComplexOscillator getOscillator()
|
||||
{
|
||||
return mOscillator;
|
||||
}
|
||||
@@ -275,7 +260,6 @@ public class SynthesizerViewer extends JFrame
|
||||
private TwoChannelSynthesizerM2 mSynthesizer;
|
||||
private FS4DownConverter mFS4DownConverter = new FS4DownConverter();
|
||||
private int mSamplesPerCycle = CHANNEL_SAMPLE_RATE / DATA_GENERATOR_FRAME_RATE;
|
||||
private ReusableComplexBufferQueue mReusableComplexBufferQueue = new ReusableComplexBufferQueue("SynthesizerViewer");
|
||||
|
||||
public DataGenerationManager()
|
||||
{
|
||||
@@ -293,22 +277,15 @@ public class SynthesizerViewer extends JFrame
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
ReusableComplexBuffer channel1Buffer = mReusableComplexBufferQueue.getBuffer(mSamplesPerCycle);
|
||||
getChannel1ControlPanel().getOscillator().generateComplex(channel1Buffer);
|
||||
ComplexSamples channel1Buffer = getChannel1ControlPanel().getOscillator().generateComplexSamples(mSamplesPerCycle);
|
||||
ComplexSamples channel2Buffer = getChannel2ControlPanel().getOscillator().generateComplexSamples(mSamplesPerCycle);
|
||||
|
||||
ReusableComplexBuffer channel2Buffer = mReusableComplexBufferQueue.getBuffer(mSamplesPerCycle);
|
||||
getChannel2ControlPanel().getOscillator().generateComplex(channel2Buffer);
|
||||
ComplexSamples synthesizedBuffer = mSynthesizer.process(channel1Buffer, channel2Buffer);
|
||||
getChannel1Panel().receive(new FloatNativeBuffer(channel1Buffer, System.currentTimeMillis()));
|
||||
|
||||
channel1Buffer.incrementUserCount();
|
||||
channel2Buffer.incrementUserCount();
|
||||
getChannel2Panel().receive(new FloatNativeBuffer(channel2Buffer, System.currentTimeMillis()));
|
||||
|
||||
ReusableComplexBuffer synthesizedBuffer = mSynthesizer.process(channel1Buffer, channel2Buffer);
|
||||
|
||||
getChannel1Panel().receive(channel1Buffer);
|
||||
|
||||
getChannel2Panel().receive(channel2Buffer);
|
||||
|
||||
getSpectrumPanel().receive(synthesizedBuffer);
|
||||
getSpectrumPanel().receive(new FloatNativeBuffer(synthesizedBuffer, System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,27 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.gui.instrument;
|
||||
|
||||
import io.github.dsheirer.buffer.INativeBuffer;
|
||||
import io.github.dsheirer.gui.instrument.decoder.AbstractDecoderPane;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import io.github.dsheirer.source.IControllableFileSource;
|
||||
import io.github.dsheirer.source.IFrameLocationListener;
|
||||
import io.github.dsheirer.source.wave.ComplexWaveSource;
|
||||
@@ -65,7 +62,8 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
private AbstractDecoderPane mSampleRateListener;
|
||||
|
||||
private IControllableFileSource mControllableFileSource;
|
||||
private ReusableBufferBroadcaster mReusableBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<float[]> mRealBufferBroadcaster = new Broadcaster<>();
|
||||
private Broadcaster<INativeBuffer> mNativeBufferBroadcaster = new Broadcaster<>();
|
||||
|
||||
public PlaybackController()
|
||||
{
|
||||
@@ -96,7 +94,7 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
{
|
||||
mControllableFileSource = new ComplexWaveSource(file);
|
||||
mControllableFileSource.setListener(this);
|
||||
((ComplexWaveSource)mControllableFileSource).setListener(mReusableBufferBroadcaster);
|
||||
((ComplexWaveSource)mControllableFileSource).setListener(mNativeBufferBroadcaster);
|
||||
mControllableFileSource.open();
|
||||
|
||||
if(mSampleRateListener != null)
|
||||
@@ -130,7 +128,7 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
{
|
||||
mControllableFileSource = new RealWaveSource(file);
|
||||
mControllableFileSource.setListener(this);
|
||||
((RealWaveSource)mControllableFileSource).setListener(mReusableBufferBroadcaster);
|
||||
((RealWaveSource)mControllableFileSource).setListener(mRealBufferBroadcaster);
|
||||
mControllableFileSource.open();
|
||||
|
||||
if(mSampleRateListener != null)
|
||||
@@ -181,19 +179,35 @@ public class PlaybackController extends HBox implements IFrameLocationListener
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds listener to receive complex buffers from this playback
|
||||
* Adds listener to receive real buffers from this playback
|
||||
*/
|
||||
public void addListener(Listener<ReusableFloatBuffer> listener)
|
||||
public void addRealListener(Listener<float[]> listener)
|
||||
{
|
||||
mReusableBufferBroadcaster.addListener(listener);
|
||||
mRealBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving complex buffers from this playback
|
||||
* Removes the listener from receiving real buffers from this playback
|
||||
*/
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
public void removeRealListener(Listener<float[]> listener)
|
||||
{
|
||||
mReusableBufferBroadcaster.removeListener(listener);
|
||||
mRealBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds listener to receive complex buffers from this playback
|
||||
*/
|
||||
public void addComplexListener(Listener<INativeBuffer> listener)
|
||||
{
|
||||
mNativeBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving compex buffers from this playback
|
||||
*/
|
||||
public void removeComplexListener(Listener<INativeBuffer> listener)
|
||||
{
|
||||
mNativeBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,12 +14,13 @@
|
||||
*
|
||||
* 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;
|
||||
|
||||
import io.github.dsheirer.gui.instrument.decoder.AbstractDecoderPane;
|
||||
import io.github.dsheirer.gui.instrument.decoder.DecoderPaneFactory;
|
||||
import io.github.dsheirer.gui.instrument.decoder.RealDecoderPane;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.P25P1Decoder;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
@@ -56,11 +56,26 @@ public class ViewerDesktop extends BorderPane
|
||||
|
||||
private void setDecoderPane(AbstractDecoderPane decoderPane)
|
||||
{
|
||||
getPlaybackController().removeListener(getDecoderPane());
|
||||
if(getDecoderPane() instanceof RealDecoderPane)
|
||||
{
|
||||
getPlaybackController().removeRealListener(getDecoderPane());
|
||||
}
|
||||
else
|
||||
{
|
||||
getPlaybackController().removeComplexListener(getDecoderPane());
|
||||
}
|
||||
getChildren().remove(getDecoderPane());
|
||||
mDecoderPane = decoderPane;
|
||||
setCenter(getDecoderPane());
|
||||
getPlaybackController().addListener(getDecoderPane());
|
||||
|
||||
if(getDecoderPane() instanceof RealDecoderPane)
|
||||
{
|
||||
getPlaybackController().addRealListener(getDecoderPane());
|
||||
}
|
||||
else
|
||||
{
|
||||
getPlaybackController().addComplexListener(getDecoderPane());
|
||||
}
|
||||
getPlaybackController().setSampleRateListener(getDecoderPane());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.gui.instrument.chart;
|
||||
|
||||
import io.github.dsheirer.buffer.ComplexCircularBuffer;
|
||||
import io.github.dsheirer.dsp.gain.ComplexGain;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ComplexPhaseLineChart extends LineChart implements Listener<ReusableComplexBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ComplexPhaseLineChart.class);
|
||||
|
||||
private static final Complex ANGLE_OFFSET_45_DEGREES = Complex.fromAngle(FastMath.PI / 4.0);
|
||||
private ComplexCircularBuffer mComplexCircularBuffer;
|
||||
private ComplexGain mComplexGain = new ComplexGain(600.0f);
|
||||
private ObservableList<Data<Integer,Float>> mPhaseValues = FXCollections.observableArrayList();
|
||||
private IntegerProperty mLengthProperty = new SimpleIntegerProperty(40);
|
||||
|
||||
public ComplexPhaseLineChart(int length)
|
||||
{
|
||||
super(new NumberAxis("Time", 1, length - 10, 2),
|
||||
new NumberAxis("Phase", -FastMath.PI, FastMath.PI, FastMath.PI / 2.0));
|
||||
|
||||
Series<Integer,Float> phaseSeries = new Series<>("Phase", mPhaseValues);
|
||||
ObservableList<Series<Integer,Float>> observableList = FXCollections.observableArrayList(phaseSeries);
|
||||
|
||||
setData(observableList);
|
||||
init(length);
|
||||
}
|
||||
|
||||
private void init(int length)
|
||||
{
|
||||
mLengthProperty.addListener(new ChangeListener<Number>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue)
|
||||
{
|
||||
mComplexCircularBuffer = new ComplexCircularBuffer(newValue.intValue());
|
||||
}
|
||||
});
|
||||
mComplexCircularBuffer = new ComplexCircularBuffer(length);
|
||||
length().setValue(length);
|
||||
|
||||
for(int x = 10; x <= length; x++)
|
||||
{
|
||||
mPhaseValues.add(new Data(x - 10, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the x-axis for displaying samples
|
||||
*/
|
||||
public IntegerProperty length()
|
||||
{
|
||||
return mLengthProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
{
|
||||
float[] samples = complexBuffer.getSamples();
|
||||
|
||||
Complex sample;
|
||||
|
||||
for(int x = 0; x < samples.length; x += 2)
|
||||
{
|
||||
sample = new Complex(samples[x], samples[x + 1]);
|
||||
Complex copy = sample.copy();
|
||||
mComplexGain.apply(copy);
|
||||
mComplexCircularBuffer.put(copy);
|
||||
}
|
||||
|
||||
complexBuffer.decrementUserCount();
|
||||
|
||||
updateChart();
|
||||
}
|
||||
|
||||
private void updateChart()
|
||||
{
|
||||
Complex[] samples = mComplexCircularBuffer.getAll();
|
||||
|
||||
for(int x = 10; x < samples.length; x++)
|
||||
{
|
||||
Complex previous = samples[x - 10].copy();
|
||||
Complex sample = samples[x].copy();
|
||||
|
||||
if(previous != null && sample != null)
|
||||
{
|
||||
// previous.normalize();
|
||||
// sample.normalize();
|
||||
previous.add(ANGLE_OFFSET_45_DEGREES);
|
||||
sample.multiply(previous.conjugate());
|
||||
// sample.normalize();
|
||||
mPhaseValues.get(x - 9).setYValue(sample.angle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,28 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.gui.instrument.chart;
|
||||
|
||||
import io.github.dsheirer.buffer.ComplexCircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import io.github.dsheirer.sample.complex.ComplexSampleListener;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
@@ -38,7 +35,7 @@ import javafx.scene.chart.XYChart;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ComplexSampleLineChart extends LineChart implements Listener<ReusableComplexBuffer>, ComplexSampleListener
|
||||
public class ComplexSampleLineChart extends LineChart implements Listener<ComplexSamples>, ComplexSampleListener
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ComplexSampleLineChart.class);
|
||||
|
||||
@@ -97,16 +94,12 @@ public class ComplexSampleLineChart extends LineChart implements Listener<Reusab
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
public void receive(ComplexSamples samples)
|
||||
{
|
||||
float[] samples = complexBuffer.getSamples();
|
||||
|
||||
for(int x = 0; x < samples.length; x += 2)
|
||||
for(int x = 0; x < samples.i().length; x++)
|
||||
{
|
||||
receive(samples[x], samples[x + 1]);
|
||||
receive(samples.i()[x], samples.q()[x]);
|
||||
}
|
||||
|
||||
complexBuffer.decrementUserCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.gui.instrument.chart;
|
||||
|
||||
import io.github.dsheirer.buffer.DoubleCircularBuffer;
|
||||
import io.github.dsheirer.dsp.fm.FMDemodulator;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class FMDemodulatedLineChart extends LineChart implements Listener<ReusableComplexBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(FMDemodulatedLineChart.class);
|
||||
|
||||
private DoubleCircularBuffer mDoubleCircularBuffer;
|
||||
private int mSamplesPerSymbol;
|
||||
private int mTwiceSamplesPerSymbol;
|
||||
private int mSeriesCount;
|
||||
private ObservableList<Series<Integer,Double>> mData = FXCollections.observableArrayList();
|
||||
private Complex mPreviousSample = new Complex(0,0);
|
||||
private int mSeriesPointer;
|
||||
private int mSamplePointer;
|
||||
|
||||
public FMDemodulatedLineChart(int samplesPerSymbol, int seriesCount)
|
||||
{
|
||||
super(new NumberAxis("Time", 1, samplesPerSymbol * 2, 2),
|
||||
new NumberAxis("Demodulated", -1.0, 1.0, 0.25));
|
||||
|
||||
mSamplesPerSymbol = samplesPerSymbol;
|
||||
mTwiceSamplesPerSymbol = mSamplesPerSymbol * 2;
|
||||
mSeriesCount = seriesCount;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
int seriesLength = 2 * mSamplesPerSymbol;
|
||||
mDoubleCircularBuffer = new DoubleCircularBuffer(seriesLength * mSeriesCount);
|
||||
|
||||
for(int x = 0; x < mSeriesCount; x++)
|
||||
{
|
||||
ObservableList<Data<Integer,Double>> series = FXCollections.observableArrayList();
|
||||
|
||||
for(int y = 0; y < seriesLength; y++)
|
||||
{
|
||||
series.add(new Data<Integer,Double>(y + 1, 0.0));
|
||||
}
|
||||
|
||||
mData.add(new Series<>(series));
|
||||
}
|
||||
|
||||
setData(mData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer complexBuffer)
|
||||
{
|
||||
float[] samples = complexBuffer.getSamples();
|
||||
|
||||
Complex sample;
|
||||
|
||||
for(int x = 0; x < samples.length; x += 2)
|
||||
{
|
||||
sample = new Complex(samples[x], samples[x + 1]);
|
||||
double demodulated = FMDemodulator.demodulate(mPreviousSample, sample);
|
||||
demodulated *= 2.0;
|
||||
|
||||
if(demodulated > 1.0)
|
||||
{
|
||||
demodulated = 1.0;
|
||||
}
|
||||
else if(demodulated < -1.0)
|
||||
{
|
||||
demodulated = -1.0;
|
||||
}
|
||||
mDoubleCircularBuffer.put(demodulated);
|
||||
mPreviousSample = sample;
|
||||
updateChart(demodulated);
|
||||
}
|
||||
|
||||
complexBuffer.decrementUserCount();
|
||||
}
|
||||
|
||||
private void updateChart(double value)
|
||||
{
|
||||
Series<Integer,Double> series = mData.get(mSeriesPointer);
|
||||
Data data = series.getData().get(mSamplePointer++);
|
||||
data.setYValue(value);
|
||||
|
||||
if(mSamplePointer >= mTwiceSamplesPerSymbol)
|
||||
{
|
||||
mSamplePointer = 0;
|
||||
mSeriesPointer++;
|
||||
|
||||
if(mSeriesPointer >= mSeriesCount)
|
||||
{
|
||||
mSeriesPointer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
/*******************************************************************************
|
||||
* 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.instrument.chart;
|
||||
|
||||
import io.github.dsheirer.buffer.RealCircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
@@ -27,7 +29,7 @@ import javafx.scene.layout.StackPane;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RealSampleLineChart extends LineChart implements Listener<ReusableFloatBuffer>
|
||||
public class RealSampleLineChart extends LineChart implements Listener<float[]>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(RealSampleLineChart.class);
|
||||
private ObservableList<Data<Integer,Float>> mSamples = FXCollections.observableArrayList();
|
||||
@@ -65,9 +67,9 @@ public class RealSampleLineChart extends LineChart implements Listener<ReusableF
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableFloatBuffer buffer)
|
||||
public void receive(float[] buffer)
|
||||
{
|
||||
for(float sample: buffer.getSamples())
|
||||
for(float sample: buffer)
|
||||
{
|
||||
mRealCircularBuffer.put(sample);
|
||||
}
|
||||
@@ -79,7 +81,5 @@ public class RealSampleLineChart extends LineChart implements Listener<ReusableF
|
||||
Data<Integer,Float> sample = mSamples.get(x);
|
||||
sample.setYValue(bufferSamples[x]);
|
||||
}
|
||||
|
||||
buffer.decrementUserCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.gui.instrument.chart;
|
||||
|
||||
@@ -28,15 +25,15 @@ import eu.hansolo.fx.charts.data.XYChartItem;
|
||||
import eu.hansolo.fx.charts.series.XYSeries;
|
||||
import io.github.dsheirer.buffer.ComplexCircularBuffer;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.paint.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SampleXYChart extends PolarChart<XYChartItem> implements Listener<ReusableComplexBuffer>
|
||||
public class SampleXYChart extends PolarChart<XYChartItem> implements Listener<ComplexSamples>
|
||||
{
|
||||
private static ObservableList<XYChartItem> sChartItemList = FXCollections.observableArrayList();
|
||||
|
||||
@@ -67,17 +64,13 @@ public class SampleXYChart extends PolarChart<XYChartItem> implements Listener<R
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer buffer)
|
||||
public void receive(ComplexSamples buffer)
|
||||
{
|
||||
float[] samples = buffer.getSamples();
|
||||
|
||||
for(int x = 0; x < samples.length; x += 2)
|
||||
for(int x = 0; x < buffer.i().length; x++)
|
||||
{
|
||||
mCircularBuffer.put(new Complex(samples[x], samples[x + 1]));
|
||||
mCircularBuffer.put(new Complex(buffer.i()[x], buffer.q()[x]));
|
||||
}
|
||||
|
||||
buffer.decrementUserCount();
|
||||
|
||||
Complex[] complexSamples = mCircularBuffer.getAll();
|
||||
|
||||
XYSeries<XYChartItem> series = getXYPane().getListOfSeries().get(0);
|
||||
|
||||
@@ -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.instrument.decoder;
|
||||
|
||||
import io.github.dsheirer.gui.instrument.chart.AFSK1200SampleBufferChart;
|
||||
@@ -23,7 +26,6 @@ import io.github.dsheirer.gui.instrument.chart.RealSampleLineChart;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
@@ -52,7 +54,7 @@ public abstract class AbstractAFSK1200Pane extends RealDecoderPane
|
||||
private void init()
|
||||
{
|
||||
//This is force-cast without type checking ....
|
||||
addListener((Listener<ReusableFloatBuffer>) getDecoder());
|
||||
addListener((Listener<float[]>) getDecoder());
|
||||
|
||||
addListener(getSampleLineChart());
|
||||
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
/*******************************************************************************
|
||||
* 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.instrument.decoder;
|
||||
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
public abstract class AbstractDecoderPane<T extends ReusableFloatBuffer> extends VBox implements Listener<T>
|
||||
public abstract class AbstractDecoderPane<T> extends VBox implements Listener<T>
|
||||
{
|
||||
abstract SampleType getSampleType();
|
||||
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
/*******************************************************************************
|
||||
* 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.instrument.decoder;
|
||||
|
||||
import io.github.dsheirer.buffer.INativeBuffer;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class ComplexDecoderPane extends AbstractDecoderPane<ReusableComplexBuffer>
|
||||
public class ComplexDecoderPane extends AbstractDecoderPane<INativeBuffer>
|
||||
{
|
||||
private ReusableBufferBroadcaster mComplexBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<INativeBuffer> mBufferBroadcaster = new Broadcaster();
|
||||
private DecoderType mDecoderType;
|
||||
|
||||
public ComplexDecoderPane(DecoderType decoderType)
|
||||
@@ -47,18 +50,18 @@ public class ComplexDecoderPane extends AbstractDecoderPane<ReusableComplexBuffe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableComplexBuffer reusableComplexBuffer)
|
||||
public void receive(INativeBuffer nativeBuffer)
|
||||
{
|
||||
mComplexBufferBroadcaster.broadcast(reusableComplexBuffer);
|
||||
mBufferBroadcaster.broadcast(nativeBuffer);
|
||||
}
|
||||
|
||||
public void addListener(Listener<ReusableComplexBuffer> listener)
|
||||
public void addListener(Listener<INativeBuffer> listener)
|
||||
{
|
||||
mComplexBufferBroadcaster.addListener(listener);
|
||||
mBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
public void removeListener(Listener<ReusableComplexBuffer> listener)
|
||||
public void removeListener(Listener<INativeBuffer> listener)
|
||||
{
|
||||
mComplexBufferBroadcaster.removeListener(listener);
|
||||
mBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.gui.instrument.decoder;
|
||||
|
||||
@@ -26,17 +23,18 @@ import io.github.dsheirer.gui.instrument.chart.DoubleLineChart;
|
||||
import io.github.dsheirer.gui.instrument.chart.EyeDiagramChart;
|
||||
import io.github.dsheirer.gui.instrument.chart.PhaseLineChart;
|
||||
import io.github.dsheirer.gui.instrument.chart.SymbolChart;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.dmr.DMRDecoderInstrumented;
|
||||
import io.github.dsheirer.module.decode.dmr.DecodeConfigDMR;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class DMRPane extends ComplexDecoderPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(DMRPane.class);
|
||||
@@ -49,7 +47,7 @@ public class DMRPane extends ComplexDecoderPane
|
||||
private PhaseLineChart mPLLPhaseErrorLineChart;
|
||||
private DoubleLineChart mPLLFrequencyLineChart;
|
||||
private DoubleLineChart mSamplesPerSymbolLineChart;
|
||||
private ReusableBufferBroadcaster mFilteredBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<ComplexSamples> mFilteredBufferBroadcaster = new Broadcaster();
|
||||
private DMRDecoderInstrumented mDecoder = new DMRDecoderInstrumented(new DecodeConfigDMR());
|
||||
|
||||
public DMRPane()
|
||||
@@ -60,7 +58,15 @@ public class DMRPane extends ComplexDecoderPane
|
||||
|
||||
private void init()
|
||||
{
|
||||
addListener(getDecoder());
|
||||
addListener(nativeBuffer ->
|
||||
{
|
||||
Iterator<ComplexSamples> iterator = nativeBuffer.iterator();
|
||||
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
getDecoder().receive(iterator.next());
|
||||
}
|
||||
});
|
||||
|
||||
getDecoder().setFilteredBufferListener(mFilteredBufferBroadcaster);
|
||||
getDecoder().setComplexSymbolListener(getSymbolChart());
|
||||
@@ -74,14 +80,7 @@ public class DMRPane extends ComplexDecoderPane
|
||||
HBox.setHgrow(getDecoderChartBox(), Priority.ALWAYS);
|
||||
getChildren().addAll(getSampleChartBox(), getDecoderChartBox());
|
||||
|
||||
mDecoder.setMessageListener(new Listener<IMessage>()
|
||||
{
|
||||
@Override
|
||||
public void receive(IMessage message)
|
||||
{
|
||||
mLog.debug(message.toString());
|
||||
}
|
||||
});
|
||||
mDecoder.setMessageListener(message -> mLog.debug(message.toString()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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.gui.instrument.decoder;
|
||||
|
||||
@@ -29,13 +26,16 @@ import io.github.dsheirer.gui.instrument.chart.SymbolChart;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.P25P1DecoderC4FMInstrumented;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class P25Phase1C4FMPane extends ComplexDecoderPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25Phase1C4FMPane.class);
|
||||
@@ -48,7 +48,7 @@ public class P25Phase1C4FMPane extends ComplexDecoderPane
|
||||
private PhaseLineChart mPLLPhaseErrorLineChart;
|
||||
private DoubleLineChart mPLLFrequencyLineChart;
|
||||
private DoubleLineChart mSamplesPerSymbolLineChart;
|
||||
private ReusableBufferBroadcaster mFilteredBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<ComplexSamples> mFilteredBufferBroadcaster = new Broadcaster();
|
||||
private P25P1DecoderC4FMInstrumented mDecoder = new P25P1DecoderC4FMInstrumented();
|
||||
|
||||
public P25Phase1C4FMPane()
|
||||
@@ -59,7 +59,15 @@ public class P25Phase1C4FMPane extends ComplexDecoderPane
|
||||
|
||||
private void init()
|
||||
{
|
||||
addListener(getDecoder());
|
||||
addListener(nativeBuffer ->
|
||||
{
|
||||
Iterator<ComplexSamples> iterator = nativeBuffer.iterator();
|
||||
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
getDecoder().receive(iterator.next());
|
||||
}
|
||||
});
|
||||
|
||||
getDecoder().setFilteredBufferListener(mFilteredBufferBroadcaster);
|
||||
getDecoder().setComplexSymbolListener(getSymbolChart());
|
||||
|
||||
@@ -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.gui.instrument.decoder;
|
||||
|
||||
@@ -30,13 +27,16 @@ import io.github.dsheirer.gui.instrument.chart.SymbolChart;
|
||||
import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.p25.phase1.P25P1DecoderLSMInstrumented;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class P25Phase1LSMPane extends ComplexDecoderPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25Phase1LSMPane.class);
|
||||
@@ -49,7 +49,7 @@ public class P25Phase1LSMPane extends ComplexDecoderPane
|
||||
private PhaseLineChart mPLLPhaseErrorLineChart;
|
||||
private DoubleLineChart mPLLFrequencyLineChart;
|
||||
private SamplesPerSymbolChart mSamplesPerSymbolLineChart;
|
||||
private ReusableBufferBroadcaster mFilteredBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<ComplexSamples> mFilteredBufferBroadcaster = new Broadcaster();
|
||||
private P25P1DecoderLSMInstrumented mDecoder = new P25P1DecoderLSMInstrumented();
|
||||
|
||||
public P25Phase1LSMPane()
|
||||
@@ -60,7 +60,15 @@ public class P25Phase1LSMPane extends ComplexDecoderPane
|
||||
|
||||
private void init()
|
||||
{
|
||||
addListener(getDecoder());
|
||||
addListener(nativeBuffer ->
|
||||
{
|
||||
Iterator<ComplexSamples> iterator = nativeBuffer.iterator();
|
||||
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
getDecoder().receive(iterator.next());
|
||||
}
|
||||
});
|
||||
|
||||
getDecoder().setFilteredBufferListener(mFilteredBufferBroadcaster);
|
||||
getDecoder().setComplexSymbolListener(getSymbolConstellationChart());
|
||||
|
||||
@@ -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.gui.instrument.decoder;
|
||||
|
||||
@@ -31,13 +28,16 @@ import io.github.dsheirer.message.IMessage;
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.DecodeConfigP25Phase2;
|
||||
import io.github.dsheirer.module.decode.p25.phase2.P25P2DecoderHDQPSKInstrumented;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class P25Phase2HDQPSKPane extends ComplexDecoderPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(P25Phase2HDQPSKPane.class);
|
||||
@@ -56,7 +56,7 @@ public class P25Phase2HDQPSKPane extends ComplexDecoderPane
|
||||
private SampleXYChart mSampleXYChart;
|
||||
|
||||
|
||||
private ReusableBufferBroadcaster mFilteredBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<ComplexSamples> mFilteredBufferBroadcaster = new Broadcaster();
|
||||
private P25P2DecoderHDQPSKInstrumented mDecoder = new P25P2DecoderHDQPSKInstrumented(new DecodeConfigP25Phase2());
|
||||
|
||||
public P25Phase2HDQPSKPane()
|
||||
@@ -67,7 +67,15 @@ public class P25Phase2HDQPSKPane extends ComplexDecoderPane
|
||||
|
||||
private void init()
|
||||
{
|
||||
addListener(getDecoder());
|
||||
addListener(nativeBuffer ->
|
||||
{
|
||||
Iterator<ComplexSamples> iterator = nativeBuffer.iterator();
|
||||
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
getDecoder().receive(iterator.next());
|
||||
}
|
||||
});
|
||||
|
||||
getDecoder().getDemodulator().setFilteredGainAppliedComplexBufferListener(getSampleXYChart());
|
||||
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* 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.instrument.decoder;
|
||||
|
||||
import io.github.dsheirer.module.decode.DecoderType;
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.SampleType;
|
||||
import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
|
||||
import io.github.dsheirer.sample.buffer.ReusableFloatBuffer;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class RealDecoderPane extends AbstractDecoderPane<ReusableFloatBuffer>
|
||||
public class RealDecoderPane extends AbstractDecoderPane<float[]>
|
||||
{
|
||||
private ReusableBufferBroadcaster mBufferBroadcaster = new ReusableBufferBroadcaster();
|
||||
private Broadcaster<float[]> mBufferBroadcaster = new Broadcaster();
|
||||
private DecoderType mDecoderType;
|
||||
|
||||
public RealDecoderPane(DecoderType decoderType)
|
||||
@@ -47,17 +49,17 @@ public class RealDecoderPane extends AbstractDecoderPane<ReusableFloatBuffer>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ReusableFloatBuffer reusableFloatBuffer)
|
||||
public void receive(float[] buffer)
|
||||
{
|
||||
mBufferBroadcaster.broadcast(reusableFloatBuffer);
|
||||
mBufferBroadcaster.broadcast(buffer);
|
||||
}
|
||||
|
||||
public void addListener(Listener<ReusableFloatBuffer> listener)
|
||||
public void addListener(Listener<float[]> listener)
|
||||
{
|
||||
mBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
public void removeListener(Listener<ReusableFloatBuffer> listener)
|
||||
public void removeListener(Listener<float[]> listener)
|
||||
{
|
||||
mBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -176,7 +173,7 @@ public class PlaylistEditor extends BorderPane
|
||||
String filename = TimeStamp.getTimeStamp("_") + "_screen_capture.png";
|
||||
final Path captureFile = mUserPreferences.getDirectoryPreference().getDirectoryScreenCapture().resolve(filename);
|
||||
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
{
|
||||
ImageIO.write(bufferedImage, "png", captureFile.toFile());
|
||||
|
||||
@@ -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
|
||||
@@ -137,7 +137,7 @@ public class BeepEditor extends ActionEditor<BeepAction>
|
||||
final TestMessage testMessage = new TestMessage();
|
||||
final Alias testAlias = new Alias("Test Alias");
|
||||
|
||||
ThreadPool.SCHEDULED.submit(() -> {
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
{
|
||||
action.execute(testAlias, testMessage);
|
||||
|
||||
@@ -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
|
||||
@@ -200,7 +200,7 @@ public class ClipEditor extends ActionEditor<ClipAction>
|
||||
final TestMessage testMessage = new TestMessage();
|
||||
final Alias testAlias = new Alias("Test Alias");
|
||||
|
||||
ThreadPool.SCHEDULED.submit(new Runnable()
|
||||
ThreadPool.CACHED.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
|
||||
@@ -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
|
||||
@@ -200,7 +200,7 @@ public class ScriptEditor extends ActionEditor<ScriptAction>
|
||||
final TestMessage testMessage = new TestMessage();
|
||||
final Alias testAlias = new Alias("Test Alias");
|
||||
|
||||
ThreadPool.SCHEDULED.submit(new Runnable()
|
||||
ThreadPool.CACHED.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
|
||||
@@ -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;
|
||||
@@ -365,7 +362,7 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
|
||||
if(!getItem().processingProperty().get())
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
mPlaylistManager.getChannelProcessingManager().start(getItem());
|
||||
@@ -386,7 +383,7 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
|
||||
}
|
||||
else
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
mPlaylistManager.getChannelProcessingManager().stop(getItem());
|
||||
|
||||
@@ -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
|
||||
@@ -155,7 +155,7 @@ public class AgencyEditor extends VBox
|
||||
|
||||
mUserPreferences.getRadioReferencePreference().setPreferredAgencyId(agency.getAgencyId(), mLevel);
|
||||
|
||||
ThreadPool.SCHEDULED.submit(() -> {
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
{
|
||||
final AgencyInfo agencyInfo = mRadioReference.getService().getAgencyInfo(agency);
|
||||
|
||||
@@ -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.gui.playlist.radioreference;
|
||||
@@ -400,7 +397,7 @@ public class AgencyFrequencyEditor extends GridPane
|
||||
|
||||
if(subCategory != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.submit(() -> {
|
||||
ThreadPool.CACHED.submit(() -> {
|
||||
try
|
||||
{
|
||||
List<Frequency> frequencies = new ArrayList<>();
|
||||
|
||||
@@ -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
|
||||
@@ -230,7 +230,7 @@ public class FrequencyEditor extends VBox
|
||||
{
|
||||
if(modeId != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
Integer parsed = null;
|
||||
|
||||
try
|
||||
|
||||
@@ -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.radioreference;
|
||||
@@ -44,7 +41,13 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.Region;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.util.StringConverter;
|
||||
import jiconfont.icons.font_awesome.FontAwesome;
|
||||
@@ -119,7 +122,7 @@ public class RadioReferenceEditor extends BorderPane implements Consumer<Authori
|
||||
|
||||
if(credentials != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> accept(credentials));
|
||||
ThreadPool.CACHED.execute(() -> accept(credentials));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +137,7 @@ public class RadioReferenceEditor extends BorderPane implements Consumer<Authori
|
||||
|
||||
final int preferredCountryId = mUserPreferences.getRadioReferencePreference().getPreferredCountryId();
|
||||
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
List<Country> countries = mRadioReference.getService().getCountries();
|
||||
@@ -565,7 +568,7 @@ public class RadioReferenceEditor extends BorderPane implements Consumer<Authori
|
||||
{
|
||||
int preferredStateId = mUserPreferences.getRadioReferencePreference().getPreferredStateId();
|
||||
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
final CountryInfo countryInfo = mRadioReference.getService().getCountryInfo(country.getCountryId());
|
||||
@@ -623,7 +626,7 @@ public class RadioReferenceEditor extends BorderPane implements Consumer<Authori
|
||||
|
||||
if(state != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
final StateInfo stateInfo = mRadioReference.getService().getStateInfo(state.getStateId());
|
||||
@@ -679,7 +682,7 @@ public class RadioReferenceEditor extends BorderPane implements Consumer<Authori
|
||||
|
||||
if(county != null)
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
final CountyInfo countyInfo = mRadioReference.getService().getCountyInfo(county.getCountyId());
|
||||
|
||||
@@ -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
|
||||
@@ -276,7 +276,7 @@ public class SystemEditor extends VBox
|
||||
mUserPreferences.getRadioReferencePreference().setPreferredSystemId(system.getSystemId(), mLevel);
|
||||
|
||||
//Retrieve the radio reference data on a separate thread and then load the editors on the FX thread
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
if(mRadioReferenceDecoder == 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;
|
||||
@@ -234,7 +231,7 @@ public class StreamingEditor extends SplitPane
|
||||
{
|
||||
if(mPlaylistManager.getRadioReference().availableProperty().get())
|
||||
{
|
||||
ThreadPool.SCHEDULED.submit(new Runnable()
|
||||
ThreadPool.CACHED.submit(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.gui.preference;
|
||||
|
||||
/**
|
||||
* View calibration preference and execute calibration request
|
||||
*/
|
||||
public class CalibrateRequest extends ViewUserPreferenceEditorRequest
|
||||
{
|
||||
public CalibrateRequest()
|
||||
{
|
||||
super(PreferenceEditorType.VECTOR_CALIBRATION);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package io.github.dsheirer.gui.preference;
|
||||
|
||||
import io.github.dsheirer.gui.preference.calibration.VectorCalibrationPreferenceEditor;
|
||||
import io.github.dsheirer.gui.preference.decoder.JmbeLibraryPreferenceEditor;
|
||||
import io.github.dsheirer.gui.preference.directory.DirectoryPreferenceEditor;
|
||||
import io.github.dsheirer.gui.preference.duplicate.DuplicateCallPreferenceEditor;
|
||||
@@ -53,6 +54,8 @@ public class PreferenceEditorFactory
|
||||
return new TunerPreferenceEditor(userPreferences);
|
||||
case TALKGROUP_FORMAT:
|
||||
return new TalkgroupFormatPreferenceEditor(userPreferences);
|
||||
case VECTOR_CALIBRATION:
|
||||
return new VectorCalibrationPreferenceEditor(userPreferences);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -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
|
||||
@@ -32,6 +32,7 @@ public enum PreferenceEditorType
|
||||
AUDIO_DUPLICATE_CALL_DETECTION("Duplicate Calls"),
|
||||
SOURCE_TUNER_CHANNELIZER("Tuner Channelizer"),
|
||||
TALKGROUP_FORMAT("Talkgroup & Radio ID"),
|
||||
VECTOR_CALIBRATION("Vector Calibration"),
|
||||
DEFAULT("Default");
|
||||
|
||||
private String mLabel;
|
||||
|
||||
@@ -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
|
||||
@@ -173,6 +173,11 @@ public class UserPreferencesEditor extends BorderPane
|
||||
treeRoot.getChildren().add(audioItem);
|
||||
audioItem.setExpanded(true);
|
||||
|
||||
TreeItem<String> cpuItem = new TreeItem<>("CPU");
|
||||
cpuItem.getChildren().add(new TreeItem(PreferenceEditorType.VECTOR_CALIBRATION));
|
||||
treeRoot.getChildren().add(cpuItem);
|
||||
cpuItem.setExpanded(true);
|
||||
|
||||
TreeItem<String> decoderItem = new TreeItem<>("Decoder");
|
||||
decoderItem.getChildren().add(new TreeItem(PreferenceEditorType.JMBE_LIBRARY));
|
||||
treeRoot.getChildren().add(decoderItem);
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.gui.preference.calibration;
|
||||
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.ButtonBar;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Dialog;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
/**
|
||||
* Dialog to prompt the user to run the calibrations.
|
||||
*/
|
||||
public class CalibrationDialog extends Dialog
|
||||
{
|
||||
private UserPreferences mUserPreferences;
|
||||
|
||||
public CalibrationDialog(UserPreferences userPreferences)
|
||||
{
|
||||
mUserPreferences = userPreferences;
|
||||
|
||||
setTitle("Calibrate CPU");
|
||||
setHeaderText("Perform CPU Calibration?");
|
||||
|
||||
Label instructionsLabel = new Label("The sdrtrunk application can run more efficiently by using Vector or Single " +
|
||||
"Instruction Multiple Data (SIMD) CPU operations. sdrtrunk must calibrate your CPU in order " +
|
||||
"to determine the best implementation.\n\n" +
|
||||
"Calibration takes a few minutes to complete.\n\n" +
|
||||
"If you click 'Cancel', you will be prompted next time you run sdrtrunk, or you can open the " +
|
||||
"User Preferences dialog from the View menu and manually start the calibration process.");
|
||||
instructionsLabel.setPrefWidth(300);
|
||||
instructionsLabel.setWrapText(true);
|
||||
|
||||
CheckBox doNotShowAgainCheckBox = new CheckBox("Do not show again");
|
||||
doNotShowAgainCheckBox.setOnAction(event ->
|
||||
{
|
||||
mUserPreferences.getVectorCalibrationPreference().setHideCalibrationDialog(doNotShowAgainCheckBox.isSelected());
|
||||
});
|
||||
|
||||
VBox.setVgrow(instructionsLabel, Priority.ALWAYS);
|
||||
VBox contentBox = new VBox();
|
||||
contentBox.setPadding(new Insets(10));
|
||||
contentBox.setSpacing(20);
|
||||
contentBox.getChildren().addAll(instructionsLabel, doNotShowAgainCheckBox);
|
||||
|
||||
getDialogPane().setContent(contentBox);
|
||||
|
||||
ButtonType calibrateButtonType = new ButtonType("Calibrate", ButtonBar.ButtonData.OK_DONE);
|
||||
ButtonType cancelButtonType = new ButtonType("Cancel", ButtonBar.ButtonData.CANCEL_CLOSE);
|
||||
getDialogPane().getButtonTypes().addAll(calibrateButtonType, cancelButtonType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* 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.gui.preference.calibration;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.LoggerContext;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.gui.preference.CalibrateRequest;
|
||||
import io.github.dsheirer.log.TextAreaLogAppender;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.preference.calibration.VectorCalibrationPreference;
|
||||
import io.github.dsheirer.util.ThreadPool;
|
||||
import io.github.dsheirer.vector.calibrate.Calibration;
|
||||
import io.github.dsheirer.vector.calibrate.CalibrationException;
|
||||
import io.github.dsheirer.vector.calibrate.CalibrationManager;
|
||||
import javafx.application.Platform;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ProgressBar;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Preference settings for duplicate call audio handling
|
||||
*/
|
||||
public class VectorCalibrationPreferenceEditor extends HBox
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(VectorCalibrationPreferenceEditor.class);
|
||||
private VectorCalibrationPreference mPreference;
|
||||
private GridPane mEditorPane;
|
||||
private ToggleSwitch mHideDialogSwitch;
|
||||
private ToggleSwitch mVectorEnabled;
|
||||
private Label mCalibrationsPendingValue;
|
||||
private Button mResetAllButton;
|
||||
private Button mCalibrateButton;
|
||||
private ProgressBar mProgressBar;
|
||||
private Label mCalibratingLabel;
|
||||
private TextArea mConsoleTextArea;
|
||||
private TextAreaLogAppender mTextAreaLogAppender;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*/
|
||||
public VectorCalibrationPreferenceEditor(UserPreferences userPreferences)
|
||||
{
|
||||
MyEventBus.getGlobalEventBus().register(this);
|
||||
mPreference = userPreferences.getVectorCalibrationPreference();
|
||||
setMaxHeight(Double.MAX_VALUE);
|
||||
setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
VBox vbox = new VBox();
|
||||
vbox.setMaxHeight(Double.MAX_VALUE);
|
||||
vbox.setMaxWidth(Double.MAX_VALUE);
|
||||
HBox.setHgrow(vbox, Priority.ALWAYS);
|
||||
|
||||
VBox.setVgrow(getEditorPane(), Priority.NEVER);
|
||||
vbox.getChildren().add(getEditorPane());
|
||||
|
||||
ScrollPane scrollPane = new ScrollPane(getConsoleTextArea());
|
||||
scrollPane.setFitToHeight(true);
|
||||
scrollPane.setFitToWidth(true);
|
||||
|
||||
VBox.setVgrow(scrollPane, Priority.ALWAYS);
|
||||
vbox.getChildren().add(scrollPane);
|
||||
getChildren().add(vbox);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void process(CalibrateRequest request)
|
||||
{
|
||||
getCalibrateButton().fire();
|
||||
}
|
||||
|
||||
private GridPane getEditorPane()
|
||||
{
|
||||
if(mEditorPane == null)
|
||||
{
|
||||
int row = 0;
|
||||
mEditorPane = new GridPane();
|
||||
mEditorPane.setPadding(new Insets(10));
|
||||
mEditorPane.setHgap(10);
|
||||
mEditorPane.setVgap(10);
|
||||
|
||||
Label titleLabel = new Label("CPU Vector SIMD Preferences");
|
||||
GridPane.setConstraints(titleLabel, 0, row++, 2, 1);
|
||||
mEditorPane.getChildren().add(titleLabel);
|
||||
|
||||
GridPane.setConstraints(getVectorEnabledToggleSwitch(), 0, row);
|
||||
GridPane.setHalignment(getVectorEnabledToggleSwitch(), HPos.RIGHT);
|
||||
mEditorPane.getChildren().add(getVectorEnabledToggleSwitch());
|
||||
|
||||
Label enableSimdLabel = new Label("Enable SIMD Vector Operations");
|
||||
GridPane.setConstraints(enableSimdLabel, 1, row++);
|
||||
mEditorPane.getChildren().add((enableSimdLabel));
|
||||
|
||||
GridPane.setConstraints(getHideDialogSwitch(), 0, row);
|
||||
GridPane.setHalignment(getHideDialogSwitch(), HPos.RIGHT);
|
||||
mEditorPane.getChildren().add(getHideDialogSwitch());
|
||||
|
||||
Label hideDialogLabel = new Label("Don't Show Calibration Dialog When New Calibrations Are Available");
|
||||
GridPane.setConstraints(hideDialogLabel, 1, row++);
|
||||
mEditorPane.getChildren().add((hideDialogLabel));
|
||||
|
||||
GridPane.setConstraints(getCalibrationsPendingValue(), 0, row);
|
||||
mEditorPane.getChildren().add(getCalibrationsPendingValue());
|
||||
|
||||
Label calibrationsPendingLabel = new Label("Calibrations To Perform");
|
||||
GridPane.setHalignment(getCalibrationsPendingValue(), HPos.RIGHT);
|
||||
GridPane.setConstraints(calibrationsPendingLabel, 1, row++);
|
||||
mEditorPane.getChildren().add(calibrationsPendingLabel);
|
||||
updateControls();
|
||||
|
||||
GridPane.setConstraints(getCalibratingLabel(), 0, row);
|
||||
mEditorPane.getChildren().add(getCalibratingLabel());
|
||||
|
||||
GridPane.setConstraints(getProgressBar(), 1, row++);
|
||||
mEditorPane.getChildren().add(getProgressBar());
|
||||
|
||||
HBox buttonsBox = new HBox();
|
||||
buttonsBox.setSpacing(10);
|
||||
buttonsBox.getChildren().addAll(getCalibrateButton(), getResetAllButton());
|
||||
GridPane.setHalignment(buttonsBox, HPos.CENTER);
|
||||
GridPane.setConstraints(buttonsBox, 0, row, 2, 1);
|
||||
mEditorPane.getChildren().add(buttonsBox);
|
||||
}
|
||||
|
||||
return mEditorPane;
|
||||
}
|
||||
|
||||
private void enableConsoleLogging()
|
||||
{
|
||||
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
|
||||
Logger logger = loggerContext.getLogger(Calibration.class);
|
||||
((ch.qos.logback.classic.Logger)logger).setLevel(Level.INFO);
|
||||
((ch.qos.logback.classic.Logger)logger).addAppender(getTextAreaLogAppender());
|
||||
getTextAreaLogAppender().start();
|
||||
}
|
||||
|
||||
private void disableConsoleLogging()
|
||||
{
|
||||
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
|
||||
Logger logger = loggerContext.getLogger(Calibration.class);
|
||||
((ch.qos.logback.classic.Logger)logger).detachAppender(getTextAreaLogAppender());
|
||||
getTextAreaLogAppender().stop();
|
||||
}
|
||||
|
||||
private TextAreaLogAppender getTextAreaLogAppender()
|
||||
{
|
||||
if(mTextAreaLogAppender == null)
|
||||
{
|
||||
mTextAreaLogAppender = new TextAreaLogAppender(getConsoleTextArea(), "My Console Logger");
|
||||
}
|
||||
|
||||
return mTextAreaLogAppender;
|
||||
}
|
||||
|
||||
private TextArea getConsoleTextArea()
|
||||
{
|
||||
if(mConsoleTextArea == null)
|
||||
{
|
||||
mConsoleTextArea = new TextArea();
|
||||
mConsoleTextArea.setDisable(true);
|
||||
mConsoleTextArea.setMaxHeight(Double.MAX_VALUE);
|
||||
mConsoleTextArea.setMaxWidth(Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
return mConsoleTextArea;
|
||||
}
|
||||
|
||||
private ProgressBar getProgressBar()
|
||||
{
|
||||
if(mProgressBar == null)
|
||||
{
|
||||
mProgressBar = new ProgressBar();
|
||||
mProgressBar.setVisible(false);
|
||||
}
|
||||
|
||||
return mProgressBar;
|
||||
}
|
||||
|
||||
private Button getResetAllButton()
|
||||
{
|
||||
if(mResetAllButton == null)
|
||||
{
|
||||
mResetAllButton = new Button("Reset All Calibrations");
|
||||
mResetAllButton.setTooltip(new Tooltip("Reset all calibrations to an Uncalibrated state"));
|
||||
mResetAllButton.setOnAction(event ->
|
||||
{
|
||||
CalibrationManager.getInstance().reset();
|
||||
updateControls();
|
||||
});
|
||||
}
|
||||
|
||||
return mResetAllButton;
|
||||
}
|
||||
|
||||
private Button getCalibrateButton()
|
||||
{
|
||||
if(mCalibrateButton == null)
|
||||
{
|
||||
mCalibrateButton = new Button("Calibrate");
|
||||
mCalibrateButton.setTooltip(new Tooltip("Calibrate the items that need calibrated"));
|
||||
mCalibrateButton.setOnAction(event ->
|
||||
{
|
||||
getCalibrateButton().setDisable(true);
|
||||
getResetAllButton().setDisable(true);
|
||||
getConsoleTextArea().clear();
|
||||
getConsoleTextArea().appendText("Calibrating. Each calibration lasts 20 - 40 seconds.");
|
||||
enableConsoleLogging();
|
||||
getCalibratingLabel().setVisible(true);
|
||||
getProgressBar().setVisible(true);
|
||||
getProgressBar().setProgress(0.0);
|
||||
|
||||
ThreadPool.CACHED.submit(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
CalibrationManager manager = CalibrationManager.getInstance();
|
||||
List<Calibration> calibrations = manager.getUncalibrated();
|
||||
int counter = 0;
|
||||
for(Calibration calibration: calibrations)
|
||||
{
|
||||
counter++;
|
||||
|
||||
final String message = "\n\nCalibration [" + counter + "/" + calibrations.size() + "] - " + calibration.getType();
|
||||
Platform.runLater(() -> getConsoleTextArea().appendText(message));
|
||||
|
||||
try
|
||||
{
|
||||
calibration.calibrate();
|
||||
|
||||
final double progress = (double)counter / (double)calibrations.size();
|
||||
Platform.runLater(() -> getProgressBar().setProgress(progress));
|
||||
}
|
||||
catch(CalibrationException ce)
|
||||
{
|
||||
mLog.error("Calibration error for " + calibration.getType(), ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
mLog.error("Error while performing calibrations", t);
|
||||
}
|
||||
|
||||
Platform.runLater(() ->
|
||||
{
|
||||
getConsoleTextArea().appendText("\nCalibration Complete!\nNote: restart the application to use these new settings.");
|
||||
getCalibratingLabel().setVisible(false);
|
||||
getProgressBar().setVisible(false);
|
||||
updateControls();
|
||||
disableConsoleLogging();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return mCalibrateButton;
|
||||
}
|
||||
|
||||
private Label getCalibratingLabel()
|
||||
{
|
||||
if(mCalibratingLabel == null)
|
||||
{
|
||||
mCalibratingLabel = new Label("Calibrating:");
|
||||
mCalibratingLabel.setVisible(false);
|
||||
}
|
||||
|
||||
return mCalibratingLabel;
|
||||
}
|
||||
|
||||
private void updateControls()
|
||||
{
|
||||
int pending = CalibrationManager.getInstance().getUncalibrated().size();
|
||||
int total = CalibrationManager.getInstance().getCalibrationTypes().size();
|
||||
getCalibrationsPendingValue().setText(String.valueOf(pending));
|
||||
getCalibrateButton().setDisable(pending == 0);
|
||||
getResetAllButton().setDisable(pending == total);
|
||||
}
|
||||
|
||||
private Label getCalibrationsPendingValue()
|
||||
{
|
||||
if(mCalibrationsPendingValue == null)
|
||||
{
|
||||
mCalibrationsPendingValue = new Label(" ");
|
||||
}
|
||||
|
||||
return mCalibrationsPendingValue;
|
||||
}
|
||||
|
||||
private ToggleSwitch getVectorEnabledToggleSwitch()
|
||||
{
|
||||
if(mVectorEnabled == null)
|
||||
{
|
||||
mVectorEnabled = new ToggleSwitch();
|
||||
mVectorEnabled.setTooltip(new Tooltip("Allow sdrtrunk to use optimized vector operations when supported by your CPU"));
|
||||
mVectorEnabled.setSelected(mPreference.isVectorEnabled());
|
||||
mVectorEnabled.selectedProperty()
|
||||
.addListener((observable, oldValue, enabled) -> mPreference.setVectorEnabled(enabled));
|
||||
}
|
||||
|
||||
return mVectorEnabled;
|
||||
}
|
||||
|
||||
private ToggleSwitch getHideDialogSwitch()
|
||||
{
|
||||
if(mHideDialogSwitch == null)
|
||||
{
|
||||
mHideDialogSwitch = new ToggleSwitch();
|
||||
mHideDialogSwitch.setTooltip(new Tooltip("Don't show dialog when new calibrations are available"));
|
||||
mHideDialogSwitch.setSelected(mPreference.isHideCalibrationDialog());
|
||||
mHideDialogSwitch.selectedProperty().addListener((observable, oldValue, hide) -> mPreference.setHideCalibrationDialog(hide));
|
||||
}
|
||||
|
||||
return mHideDialogSwitch;
|
||||
}
|
||||
}
|
||||
@@ -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.preference.decoder;
|
||||
@@ -168,7 +167,7 @@ public class JmbeLibraryPreferenceEditor extends VBox
|
||||
*/
|
||||
private void checkForUpdatedLibrary()
|
||||
{
|
||||
ThreadPool.SCHEDULED.execute(() -> {
|
||||
ThreadPool.CACHED.execute(() -> {
|
||||
try
|
||||
{
|
||||
Version current = mUserPreferences.getJmbeLibraryPreference().getCurrentVersion();
|
||||
|
||||
@@ -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
|
||||
@@ -19,7 +19,8 @@
|
||||
|
||||
package io.github.dsheirer.gui.preference.playback;
|
||||
|
||||
import io.github.dsheirer.dsp.mixer.Oscillator;
|
||||
import io.github.dsheirer.dsp.oscillator.IRealOscillator;
|
||||
import io.github.dsheirer.dsp.oscillator.ScalarRealOscillator;
|
||||
|
||||
/**
|
||||
* Utility for generating tones for audio clips
|
||||
@@ -38,9 +39,9 @@ public class ToneUtil
|
||||
*/
|
||||
public static float[] getTone(ToneFrequency toneFrequency, ToneVolume toneVolume, int sampleCount)
|
||||
{
|
||||
Oscillator oscillator = new Oscillator(toneFrequency.getValue(), 8000.0);
|
||||
IRealOscillator oscillator = new ScalarRealOscillator(toneFrequency.getValue(), 8000.0);
|
||||
|
||||
float[] samples = oscillator.generateReal(sampleCount);
|
||||
float[] samples = oscillator.generate(sampleCount);
|
||||
|
||||
double gain = MAX_TONE_VOLUME * ((double)toneVolume.getValue() / 10.0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user