Merge branch 'master' into 39-polyphase-channelizer

# Conflicts:
#	src/main/java/io/github/dsheirer/buffer/FloatCircularBuffer.java
#	src/main/java/io/github/dsheirer/dsp/filter/FilterFactory.java
#	src/main/java/io/github/dsheirer/dsp/filter/design/FilterView.java
#	src/main/java/io/github/dsheirer/dsp/filter/design/FilterViewer.java
#	src/main/java/io/github/dsheirer/dsp/filter/fir/complex/ComplexFIRFilter.java
#	src/main/java/io/github/dsheirer/dsp/gain/ComplexFeedForwardGainControl.java
#	src/main/java/io/github/dsheirer/dsp/mixer/Oscillator.java
#	src/main/java/io/github/dsheirer/dsp/psk/LSMDemodulator.java
#	src/main/java/io/github/dsheirer/module/decode/Decoder.java
#	src/main/java/io/github/dsheirer/module/decode/DecoderFactory.java
#	src/main/java/io/github/dsheirer/module/decode/p25/P25Decoder.java
#	src/main/java/io/github/dsheirer/module/decode/p25/P25_C4FMDecoder.java
#	src/main/java/io/github/dsheirer/module/decode/p25/P25_LSMDecoder.java
#	src/main/java/io/github/dsheirer/source/tuner/TunerChannelSource.java
#	src/main/java/io/github/dsheirer/source/tuner/TunerModel.java
#	src/main/java/io/github/dsheirer/source/tuner/TunerSourceEditor.java
#	src/main/java/io/github/dsheirer/spectrum/ChannelSpectrumPanel.java
This commit is contained in:
Denny
2018-03-18 05:19:33 -04:00
89 changed files with 7253 additions and 2885 deletions

View File

@@ -1,3 +1,18 @@
/*******************************************************************************
* 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.source;
import javax.sound.sampled.UnsupportedAudioFileException;
@@ -10,22 +25,24 @@ import java.io.IOException;
*/
public interface IControllableFileSource
{
/**
* Opens the file source
*/
public void open() throws IOException, UnsupportedAudioFileException;
public void close() throws IOException;
public File getFile();
public void next( int frames ) throws IOException;
public void next( int frames, boolean broadcast ) throws IOException;
public long getFrameCount() throws IOException;
public void setListener( IFrameLocationListener listener );
public void removeListener( IFrameLocationListener listener );
/**
* Opens the file source
*/
public void open() throws IOException, UnsupportedAudioFileException;
public void close() throws IOException;
public File getFile();
public void next(int frames) throws IOException;
public void next(int frames, boolean broadcast) throws IOException;
public long getFrameCount() throws IOException;
public int getSampleRate();
public void setListener(IFrameLocationListener listener);
public void removeListener(IFrameLocationListener listener);
}

View File

@@ -25,7 +25,8 @@ import io.github.dsheirer.source.mixer.MixerSourceEditor;
import io.github.dsheirer.source.tuner.TunerSourceEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -43,7 +44,7 @@ public class SourceConfigurationEditor extends Editor<Channel>
mMixerSourceEditor = new MixerSourceEditor( sourceManager );
mMixerSourceEditor.setSaveRequestListener( this );
mTunerSourceEditor = new TunerSourceEditor();
mTunerSourceEditor = new TunerSourceEditor(sourceManager.getTunerModel());
mTunerSourceEditor.setSaveRequestListener( this );
init();

View File

@@ -59,6 +59,11 @@ public class SourceManager
return mTunerManager;
}
public TunerModel getTunerModel()
{
return mTunerModel;
}
public Source getSource(SourceConfiguration config, int bandwidth)
throws SourceException
{

View File

@@ -1,6 +1,6 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 Dennis Sheirer
* 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
@@ -32,6 +32,7 @@ public class SourceConfigTuner extends SourceConfiguration
private long mFrequency = 0;
private int mBandwidth = 12500;
private String mPreferredTuner;
public SourceConfigTuner()
{
@@ -57,6 +58,34 @@ public class SourceConfigTuner extends SourceConfiguration
mFrequency = frequency;
}
/**
* Preferred tuner to use for this configuration.
* @return tuner name or null
*/
@JacksonXmlProperty(isAttribute = true, localName = "preferred_tuner")
public String getPreferredTuner()
{
return mPreferredTuner;
}
/**
* Indicates if this configuration has a specified preferred tuner
*/
@JsonIgnore
public boolean hasPreferredTuner()
{
return mPreferredTuner != null;
}
/**
* Specifies the preferred tuner to use for this configuration
* @param preferredTuner to use, if available
*/
public void setPreferredTuner(String preferredTuner)
{
mPreferredTuner = preferredTuner;
}
@JsonIgnore
@Override
public String getDescription()

View File

@@ -71,14 +71,36 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
return null;
}
public void addTuners(List<Tuner> Tuners)
/**
* Find a tuner that matches the name argument
*
* @param name of the tuner
* @return named tuner or null
*/
public Tuner getTuner(String name)
{
for(Tuner tuner : Tuners)
if(name != null)
{
addTuner(tuner);
for(Tuner tuner: mTuners)
{
if(tuner.getName().equalsIgnoreCase(name))
{
return tuner;
}
}
}
return null;
}
public void addTuners( List<Tuner> Tuners )
{
for( Tuner tuner: Tuners )
{
addTuner( tuner );
}
}
/**
* Adds the Tuner to this model
*/
@@ -262,27 +284,52 @@ public class TunerModel extends AbstractTableModel implements Listener<TunerEven
*/
public Source getSource(SourceConfigTuner config, int bandwidth)
{
TunerChannelSource retVal = null;
TunerChannelSource retVal = null;
TunerChannel tunerChannel = config.getTunerChannel();
tunerChannel.setBandwidth( bandwidth );
Iterator<Tuner> it = mTuners.iterator();
Tuner tuner;
TunerChannel tunerChannel = config.getTunerChannel();
tunerChannel.setBandwidth(bandwidth);
Iterator<Tuner> it = mTuners.iterator();
Tuner tuner;
while(it.hasNext() && retVal == null)
if(config.hasPreferredTuner())
{
tuner = it.next();
tuner = getTuner(config.getPreferredTuner());
try
if(tuner != null)
{
try
{
retVal = tuner.getChannel( tunerChannel );
if(retVal != null)
{
return retVal;
}
}
catch(Exception e)
{
//Fall through to logger below
}
}
mLog.info("Unable to source channel [" + config.getFrequency() + "] from preferred tuner [" +
config.getPreferredTuner() + "] - searching for another tuner");
}
while( it.hasNext() && retVal == null )
{
tuner = it.next();
try
{
retVal = tuner.getChannelSourceManager().getSource(tunerChannel);
}
catch(Exception e)
{
mLog.error("Error obtaining channel source from tuner [" + tuner.getName() + "]", e);
mLog.error( "error obtaining channel from tuner [" + tuner.getName() + "]", e );
}
}

View File

@@ -1,17 +1,17 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 Dennis Sheirer
*
* 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/>
******************************************************************************/
@@ -26,70 +26,164 @@ import io.github.dsheirer.source.config.SourceConfigTuner;
import io.github.dsheirer.source.config.SourceConfiguration;
import net.miginfocom.swing.MigLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TunerSourceEditor extends Editor<Channel>
{
private static final long serialVersionUID = 1L;
private JFrequencyControl mFrequencyControl;
private static final long serialVersionUID = 1L;
private static final String NO_PREFERRED_TUNER = "(none)";
private static final String UNAVAILABLE_TUNER = " (unavailable)";
private JFrequencyControl mFrequencyControl;
private JComboBox<String> mTunerNameComboBox;
private TunerModel mTunerModel;
private List<String> mCurrentTunerNames;
public TunerSourceEditor()
{
init();
}
public TunerSourceEditor(TunerModel tunerModel)
{
mTunerModel = tunerModel;
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0", "[left]", "" ) );
mFrequencyControl = new JFrequencyControl();
mFrequencyControl.setEnabled( false );
mFrequencyControl.addListener( new ISourceEventProcessor()
{
@Override
public void process(SourceEvent event )
{
setModified( true );
}
} );
add( mFrequencyControl );
}
private void init()
{
loadTunerNames();
public void save()
{
if( hasItem() && isModified() )
{
SourceConfigTuner config = new SourceConfigTuner();
config.setFrequency( mFrequencyControl.getFrequency() );
getItem().setSourceConfiguration( config );
}
setLayout(new MigLayout("insets 0 0 0 0", "[left]", ""));
mFrequencyControl = new JFrequencyControl();
mFrequencyControl.setEnabled(false);
mFrequencyControl.addListener(new IFrequencyChangeProcessor()
{
@Override
public void frequencyChanged(FrequencyChangeEvent event)
{
setModified(true);
}
});
add(mFrequencyControl);
setModified( false );
}
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]));
mTunerNameComboBox.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
setModified(true);
}
});
add(new JLabel("Preferred Tuner:"));
add(mTunerNameComboBox);
}
@Override
public void setItem( Channel item )
{
super.setItem( item );
private void loadTunerNames()
{
mCurrentTunerNames = new ArrayList<>();
if( hasItem() )
{
SourceConfiguration config = getItem().getSourceConfiguration();
for(Tuner tuner: mTunerModel.getTuners())
{
mCurrentTunerNames.add(tuner.getName());
}
mFrequencyControl.setEnabled( true );
Collections.sort(mCurrentTunerNames);
if( config instanceof SourceConfigTuner )
{
mFrequencyControl.setFrequency( ((SourceConfigTuner)config).getFrequency(), false );
setModified( false );
}
else
{
mFrequencyControl.setFrequency( 101000000, false );
setModified( true );
}
}
else
{
mFrequencyControl.setEnabled( false );
setModified( false );
}
}
}
mCurrentTunerNames.add(0, NO_PREFERRED_TUNER);
}
private void updateTunerNameCombo(String preferredTuner)
{
if(preferredTuner != null && !mCurrentTunerNames.contains(preferredTuner))
{
List<String> updatedTunerNameList = new ArrayList<>(mCurrentTunerNames);
String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER;
updatedTunerNameList.add(unavailableTuner);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
mTunerNameComboBox.setSelectedItem(unavailableTuner);
}
else
{
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
if(preferredTuner == null)
{
mTunerNameComboBox.setSelectedItem(NO_PREFERRED_TUNER);
}
else
{
mTunerNameComboBox.setSelectedItem(preferredTuner);
}
}
}
public void save()
{
if(hasItem() && isModified())
{
SourceConfigTuner config = new SourceConfigTuner();
config.setFrequency(mFrequencyControl.getFrequency());
String preferredTuner = (String)mTunerNameComboBox.getSelectedItem();
if(preferredTuner != null)
{
if(preferredTuner.equalsIgnoreCase(NO_PREFERRED_TUNER))
{
config.setPreferredTuner(null);
}
else if(preferredTuner.contains(UNAVAILABLE_TUNER))
{
//don't do anything - the config already contains this unavailable tuner name
}
else
{
config.setPreferredTuner(preferredTuner);
}
}
getItem().setSourceConfiguration(config);
}
setModified(false);
}
@Override
public void setItem(Channel item)
{
super.setItem(item);
if(hasItem())
{
SourceConfiguration config = getItem().getSourceConfiguration();
mFrequencyControl.setEnabled(true);
if(config instanceof SourceConfigTuner)
{
SourceConfigTuner tunerConfig = (SourceConfigTuner)config;
mFrequencyControl.setFrequency(tunerConfig.getFrequency(), false);
updateTunerNameCombo(tunerConfig.getPreferredTuner());
setModified(false);
}
else
{
mFrequencyControl.setFrequency(101000000, false);
setModified(true);
}
}
else
{
mFrequencyControl.setEnabled(false);
setModified(false);
}
}
}

View File

@@ -147,13 +147,8 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
if(mInputStream != null)
{
mInputStream.close();
mInputStream = null;
}
else
{
throw new IOException("Can't close wave source - was not opened");
}
mInputStream = null;
}
/**