126 - Significant improvement in processor and memory utilization. Refactors all USB tuner sample processing with a new USBTransferProcessor class. LibUSB transfer timeout processing is now consolidated under the TunerManager and tuners register with this singleton to auto-start or auto-stop USB bulk transfer processing. Resolves long-standing issue impacting multi-tuner use where the second and subsequent tuners may have been routinely starved for LibUSB processing time under heavy-loading. All tuner buffer threaded processing is now handled as runnables in the scheduled thread pool, eliminating tuner-dedicated processing threads. Added tuner buffer size management to prevent memory blow-out when down-stream processing is either lagging or impacted by java garbage collection operations. Both tuners and individual DDC channels now have bounded sample buffer queues that automatically enter and exit overflow mode when predefined max/reset thresholds are met. When any queue goes into overflow mode, sample buffers are simply dropped in favor of preserving program/memory stability.

This commit is contained in:
Denny
2017-01-28 09:08:11 -05:00
parent b9e1efa92f
commit a302d098de
11 changed files with 1748 additions and 2007 deletions

View File

@@ -1,30 +1,27 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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/>
* sdrtrunk
* Copyright (C) 2014-2017 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 source.tuner.fcd.proplusV2;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.usb4java.Device;
import org.usb4java.DeviceDescriptor;
import source.SourceException;
import source.tuner.MixerTunerType;
import source.tuner.TunerClass;
@@ -33,197 +30,200 @@ import source.tuner.configuration.TunerConfiguration;
import source.tuner.fcd.FCDCommand;
import source.tuner.fcd.FCDTunerController;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class FCD2TunerController extends FCDTunerController
{
private final static Logger mLog = LoggerFactory.getLogger( FCD2TunerController.class );
private final static Logger mLog = LoggerFactory.getLogger(FCD2TunerController.class);
public static final int MINIMUM_TUNABLE_FREQUENCY = 150000;
public static final int MAXIMUM_TUNABLE_FREQUENCY = 2050000000;
public static final int SAMPLE_RATE = 192000;
public FCD2TunerController( Device device, DeviceDescriptor descriptor )
{
super( device, descriptor,
(int)MixerTunerType.FUNCUBE_DONGLE_PRO_PLUS.getAudioFormat().getSampleRate(),
MINIMUM_TUNABLE_FREQUENCY, MAXIMUM_TUNABLE_FREQUENCY );
}
public static final int MINIMUM_TUNABLE_FREQUENCY = 150000;
public static final int MAXIMUM_TUNABLE_FREQUENCY = 2050000000;
public static final int SAMPLE_RATE = 192000;
public void init() throws SourceException
{
super.init();
public FCD2TunerController(Device device, DeviceDescriptor descriptor)
{
super(device, descriptor,
(int)MixerTunerType.FUNCUBE_DONGLE_PRO_PLUS.getAudioFormat().getSampleRate(),
MINIMUM_TUNABLE_FREQUENCY, MAXIMUM_TUNABLE_FREQUENCY);
}
mFrequencyController.setSampleRate( SAMPLE_RATE );
public void init() throws SourceException
{
super.init();
try
{
setFCDMode( Mode.APPLICATION );
}
catch( Exception e )
{
throw new SourceException( "error setting Mode to APPLICATION", e );
}
}
public int getCurrentSampleRate()
{
return SAMPLE_RATE;
}
mFrequencyController.setSampleRate(SAMPLE_RATE);
@Override
try
{
setFCDMode(Mode.APPLICATION);
}
catch(Exception e)
{
throw new SourceException("error setting Mode to APPLICATION", e);
}
}
public int getCurrentSampleRate()
{
return SAMPLE_RATE;
}
@Override
public TunerClass getTunerClass()
{
return TunerClass.FUNCUBE_DONGLE_PRO_PLUS;
return TunerClass.FUNCUBE_DONGLE_PRO_PLUS;
}
@Override
@Override
public TunerType getTunerType()
{
return TunerType.FUNCUBE_DONGLE_PRO_PLUS;
return TunerType.FUNCUBE_DONGLE_PRO_PLUS;
}
public void setLNAGain( boolean enabled ) throws SourceException
{
try
{
send( FCDCommand.APP_SET_LNA_GAIN, enabled ? 1 : 0 );
}
catch ( Exception e )
{
throw new SourceException( "error while setting LNA Gain", e );
}
}
public void setMixerGain( boolean enabled ) throws SourceException
{
try
{
send( FCDCommand.APP_SET_MIXER_GAIN, enabled ? 1 : 0 );
}
catch ( Exception e )
{
throw new SourceException( "error while setting Mixer Gain", e );
}
}
@Override
public void apply( TunerConfiguration config ) throws SourceException
public void setLNAGain(boolean enabled) throws SourceException
{
if( config instanceof FCD2TunerConfiguration )
{
FCD2TunerConfiguration fcd2 = (FCD2TunerConfiguration)config;
setFrequencyCorrection( fcd2.getFrequencyCorrection() );
setFrequency( fcd2.getFrequency() );
setLNAGain( fcd2.getGainLNA() );
setMixerGain( fcd2.getGainMixer() );
try
{
setFrequency( fcd2.getFrequency() );
}
catch( SourceException se )
{
//Do nothing, we couldn't set the frequency
}
}
try
{
send(FCDCommand.APP_SET_LNA_GAIN, enabled ? 1 : 0);
}
catch(Exception e)
{
throw new SourceException("error while setting LNA Gain", e);
}
}
public int getDCCorrection()
{
int dcCorrection = -999;
try
{
ByteBuffer buffer = send( FCDCommand.APP_GET_DC_CORRECTION );
buffer.order( ByteOrder.LITTLE_ENDIAN );
return buffer.getInt( 2 );
}
catch ( Exception e )
{
mLog.error( "error getting dc correction value", e );
}
return dcCorrection;
}
public void setDCCorrection( int value )
{
try
{
send( FCDCommand.APP_SET_DC_CORRECTION, value );
}
catch ( Exception e )
{
mLog.error( "error setting dc correction to [" + value + "]", e );
}
}
public int getIQCorrection()
{
int iqCorrection = -999;
try
{
ByteBuffer buffer = send( FCDCommand.APP_GET_IQ_CORRECTION );
buffer.order( ByteOrder.LITTLE_ENDIAN );
return buffer.getInt( 2 );
}
catch ( Exception e )
{
mLog.error( "error reading IQ correction value", e );
}
return iqCorrection;
}
public void setIQCorrection( int value )
{
try
{
send( FCDCommand.APP_SET_IQ_CORRECTION, value );
}
catch ( Exception e )
{
mLog.error( "error setting IQ correction to [" + value + "]", e );
}
}
public enum Block
{
CELLULAR_BAND_BLOCKED( "Blocked" ),
NO_BAND_BLOCK( "Unblocked" ),
UNKNOWN( "Unknown" );
private String mLabel;
private Block( String label )
{
mLabel = label;
}
public String getLabel()
{
return mLabel;
}
public static Block getBlock( String block )
{
Block retVal = UNKNOWN;
public void setMixerGain(boolean enabled) throws SourceException
{
try
{
send(FCDCommand.APP_SET_MIXER_GAIN, enabled ? 1 : 0);
}
catch(Exception e)
{
throw new SourceException("error while setting Mixer Gain", e);
}
}
if( block.equalsIgnoreCase( "No blk" ) )
{
retVal = NO_BAND_BLOCK;
}
else if( block.equalsIgnoreCase( "Cell blk" ) )
{
retVal = CELLULAR_BAND_BLOCKED;
}
return retVal;
}
}
@Override
public void apply(TunerConfiguration config) throws SourceException
{
if(config instanceof FCD2TunerConfiguration)
{
FCD2TunerConfiguration fcd2 = (FCD2TunerConfiguration)config;
setFrequencyCorrection(fcd2.getFrequencyCorrection());
setFrequency(fcd2.getFrequency());
setLNAGain(fcd2.getGainLNA());
setMixerGain(fcd2.getGainMixer());
try
{
setFrequency(fcd2.getFrequency());
}
catch(SourceException se)
{
//Do nothing, we couldn't set the frequency
}
}
}
public int getDCCorrection()
{
int dcCorrection = -999;
try
{
ByteBuffer buffer = send(FCDCommand.APP_GET_DC_CORRECTION);
buffer.order(ByteOrder.LITTLE_ENDIAN);
return buffer.getInt(2);
}
catch(Exception e)
{
mLog.error("error getting dc correction value", e);
}
return dcCorrection;
}
public void setDCCorrection(int value)
{
try
{
send(FCDCommand.APP_SET_DC_CORRECTION, value);
}
catch(Exception e)
{
mLog.error("error setting dc correction to [" + value + "]", e);
}
}
public int getIQCorrection()
{
int iqCorrection = -999;
try
{
ByteBuffer buffer = send(FCDCommand.APP_GET_IQ_CORRECTION);
buffer.order(ByteOrder.LITTLE_ENDIAN);
return buffer.getInt(2);
}
catch(Exception e)
{
mLog.error("error reading IQ correction value", e);
}
return iqCorrection;
}
public void setIQCorrection(int value)
{
try
{
send(FCDCommand.APP_SET_IQ_CORRECTION, value);
}
catch(Exception e)
{
mLog.error("error setting IQ correction to [" + value + "]", e);
}
}
public enum Block
{
CELLULAR_BAND_BLOCKED("Blocked"),
NO_BAND_BLOCK("Unblocked"),
UNKNOWN("Unknown");
private String mLabel;
private Block(String label)
{
mLabel = label;
}
public String getLabel()
{
return mLabel;
}
public static Block getBlock(String block)
{
Block retVal = UNKNOWN;
if(block.equalsIgnoreCase("No blk"))
{
retVal = NO_BAND_BLOCK;
}
else if(block.equalsIgnoreCase("Cell blk"))
{
retVal = CELLULAR_BAND_BLOCKED;
}
return retVal;
}
}
}