|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
/*******************************************************************************
|
|
|
|
/*******************************************************************************
|
|
|
|
* SDR Trunk
|
|
|
|
* SDR Trunk
|
|
|
|
* Copyright (C) 2014-2016 Dennis Sheirer
|
|
|
|
* Copyright (C) 2014-2017 Dennis Sheirer
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
@@ -17,13 +17,8 @@
|
|
|
|
******************************************************************************/
|
|
|
|
******************************************************************************/
|
|
|
|
package source.tuner;
|
|
|
|
package source.tuner;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.SortedSet;
|
|
|
|
|
|
|
|
import java.util.concurrent.ConcurrentSkipListSet;
|
|
|
|
|
|
|
|
import java.util.concurrent.RejectedExecutionException;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
|
|
import source.SourceException;
|
|
|
|
import source.SourceException;
|
|
|
|
import source.tuner.configuration.TunerConfiguration;
|
|
|
|
import source.tuner.configuration.TunerConfiguration;
|
|
|
|
import source.tuner.frequency.FrequencyChangeEvent;
|
|
|
|
import source.tuner.frequency.FrequencyChangeEvent;
|
|
|
|
@@ -32,10 +27,13 @@ import source.tuner.frequency.FrequencyController;
|
|
|
|
import source.tuner.frequency.FrequencyController.Tunable;
|
|
|
|
import source.tuner.frequency.FrequencyController.Tunable;
|
|
|
|
import source.tuner.frequency.IFrequencyChangeProcessor;
|
|
|
|
import source.tuner.frequency.IFrequencyChangeProcessor;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.SortedSet;
|
|
|
|
|
|
|
|
import java.util.concurrent.ConcurrentSkipListSet;
|
|
|
|
|
|
|
|
import java.util.concurrent.RejectedExecutionException;
|
|
|
|
|
|
|
|
|
|
|
|
public abstract class TunerController implements Tunable, IFrequencyChangeProcessor
|
|
|
|
public abstract class TunerController implements Tunable, IFrequencyChangeProcessor
|
|
|
|
{
|
|
|
|
{
|
|
|
|
private final static Logger mLog =
|
|
|
|
private final static Logger mLog = LoggerFactory.getLogger(TunerController.class);
|
|
|
|
LoggerFactory.getLogger( TunerController.class );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* List of currently tuned channels being served to demod channels */
|
|
|
|
/* List of currently tuned channels being served to demod channels */
|
|
|
|
private SortedSet<TunerChannel> mTunedChannels = new ConcurrentSkipListSet<>();
|
|
|
|
private SortedSet<TunerChannel> mTunedChannels = new ConcurrentSkipListSet<>();
|
|
|
|
@@ -44,36 +42,27 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
private double mUsableBandwidthPercentage;
|
|
|
|
private double mUsableBandwidthPercentage;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Abstract tuner controller class. The tuner controller manages frequency
|
|
|
|
* Abstract tuner controller class. The tuner controller manages frequency bandwidth and currently tuned channels
|
|
|
|
* bandwidth and currently tuned channels that are being fed samples from
|
|
|
|
* that are being fed samples from the tuner.
|
|
|
|
* the tuner.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param minimumFrequency minimum uncorrected tunable frequency
|
|
|
|
* @param minimumFrequency minimum uncorrected tunable frequency
|
|
|
|
* @param maximumFrequency maximum uncorrected tunable frequency
|
|
|
|
* @param maximumFrequency maximum uncorrected tunable frequency
|
|
|
|
* @param middleUnusable is the +/- value center DC spike to avoid for channels
|
|
|
|
* @param middleUnusable is the +/- value center DC spike to avoid for channels
|
|
|
|
* @param usableBandwidthPercentage is the unusable space at the extreme ends of the spectrum
|
|
|
|
* @param usableBandwidth percentage of usable bandwidth relative to space at the extreme ends of the spectrum
|
|
|
|
*
|
|
|
|
|
|
|
|
* @throws SourceException - for any issues related to constructing the
|
|
|
|
* @throws SourceException - for any issues related to constructing the
|
|
|
|
* class, tuning a frequency, or setting the bandwidth
|
|
|
|
* class, tuning a frequency, or setting the bandwidth
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public TunerController( long minimumFrequency,
|
|
|
|
public TunerController(long minimumFrequency, long maximumFrequency, int middleUnusable, double usableBandwidth)
|
|
|
|
long maximumFrequency,
|
|
|
|
|
|
|
|
int middleUnusable,
|
|
|
|
|
|
|
|
double usableBandwidthPercentage )
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mFrequencyController = new FrequencyController( this,
|
|
|
|
mFrequencyController = new FrequencyController(this, minimumFrequency, maximumFrequency, 0.0d);
|
|
|
|
minimumFrequency,
|
|
|
|
|
|
|
|
maximumFrequency,
|
|
|
|
|
|
|
|
0.0d );
|
|
|
|
|
|
|
|
mMiddleUnusable = middleUnusable;
|
|
|
|
mMiddleUnusable = middleUnusable;
|
|
|
|
mUsableBandwidthPercentage = usableBandwidthPercentage;
|
|
|
|
mUsableBandwidthPercentage = usableBandwidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Applies the settings in the tuner configuration
|
|
|
|
* Applies the settings in the tuner configuration
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public abstract void apply( TunerConfiguration config )
|
|
|
|
public abstract void apply(TunerConfiguration config) throws SourceException;
|
|
|
|
throws SourceException;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Responds to requests to set the frequency
|
|
|
|
* Responds to requests to set the frequency
|
|
|
|
@@ -155,8 +144,7 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
private boolean canTune(TunerChannel channel)
|
|
|
|
private boolean canTune(TunerChannel channel)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//Make sure we're within the tunable frequency range of this tuner
|
|
|
|
//Make sure we're within the tunable frequency range of this tuner
|
|
|
|
if( getMinFrequency() < channel.getMinFrequency() &&
|
|
|
|
if(getMinFrequency() < channel.getMinFrequency() && getMaxFrequency() > channel.getMaxFrequency())
|
|
|
|
getMaxFrequency() > channel.getMaxFrequency() )
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//If this is the first lock, then we're good
|
|
|
|
//If this is the first lock, then we're good
|
|
|
|
if(mTunedChannels.isEmpty())
|
|
|
|
if(mTunedChannels.isEmpty())
|
|
|
|
@@ -170,8 +158,7 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
long maxLockedFrequency = mTunedChannels.last().getMaxFrequency();
|
|
|
|
long maxLockedFrequency = mTunedChannels.last().getMaxFrequency();
|
|
|
|
|
|
|
|
|
|
|
|
//Requested channel is within current locked channel frequency range
|
|
|
|
//Requested channel is within current locked channel frequency range
|
|
|
|
if( minLockedFrequency <= channel.getMinFrequency() &&
|
|
|
|
if(minLockedFrequency <= channel.getMinFrequency() && channel.getMaxFrequency() <= maxLockedFrequency)
|
|
|
|
channel.getMaxFrequency() <= maxLockedFrequency )
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -182,6 +169,7 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Requested channel is lower than the max locked frequency
|
|
|
|
//Requested channel is lower than the max locked frequency
|
|
|
|
if(channel.getMinFrequency() <= maxLockedFrequency &&
|
|
|
|
if(channel.getMinFrequency() <= maxLockedFrequency &&
|
|
|
|
maxLockedFrequency - channel.getMinFrequency() <= usableBandwidth)
|
|
|
|
maxLockedFrequency - channel.getMinFrequency() <= usableBandwidth)
|
|
|
|
@@ -195,25 +183,19 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Constructs a digital drop channel (DDC) as a tuner channel from from
|
|
|
|
* Constructs a digital drop channel (DDC) as a tuner channel from from the tuner, or returns null if the channel
|
|
|
|
* the tuner, or returns null if the channel cannot be sourced from the
|
|
|
|
* cannot be sourced from the tuner.
|
|
|
|
* tuner.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This controller can't provide a channel if the channel, along with the
|
|
|
|
* This controller can't provide a channel if the channel, along with the current set of sourced channels, can't be
|
|
|
|
* current set of sourced channels, can't be accomodated within the current
|
|
|
|
* accomodated within the current tuner bandwidth, or if a center frequency cannot be calculated that will ensure
|
|
|
|
* tuner bandwidth, or if a center frequency cannot be calculated that will
|
|
|
|
* all of the channels can be accomodated and any defined central DC spike avoided.
|
|
|
|
* ensure all of the channels can be accomodated and any defined central DC
|
|
|
|
|
|
|
|
* spike avoided.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param tuner to source the channel from
|
|
|
|
* @param tuner to source the channel from
|
|
|
|
* @param channel with defined center frequency and bandwidth
|
|
|
|
* @param channel with defined center frequency and bandwidth
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return fully constructed tuner channel or null
|
|
|
|
* @return fully constructed tuner channel or null
|
|
|
|
*
|
|
|
|
|
|
|
|
* @throws RejectedExecutionException if the decimation processor has an error
|
|
|
|
* @throws RejectedExecutionException if the decimation processor has an error
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public TunerChannelSource getChannel( Tuner tuner, TunerChannel channel )
|
|
|
|
public TunerChannelSource getChannel(Tuner tuner, TunerChannel channel) throws RejectedExecutionException
|
|
|
|
throws RejectedExecutionException
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TunerChannelSource source = null;
|
|
|
|
TunerChannelSource source = null;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -246,21 +228,20 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Indicates if the tuner's LO frequency must be updated in order to
|
|
|
|
* Indicates if the tuner's LO frequency must be updated in order to accommodate the tuner channel
|
|
|
|
* accomodate the tuner channel
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private boolean requiresLOUpdate(TunerChannel channel) throws SourceException
|
|
|
|
private boolean requiresLOUpdate(TunerChannel channel) throws SourceException
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return !( getMinTunedFrequency() <= channel.getMinFrequency() &&
|
|
|
|
boolean isBelow = channel.getMinFrequency() < getMinTunedFrequency();
|
|
|
|
channel.getMaxFrequency() <= getMaxTunedFrequency() &&
|
|
|
|
boolean isAbove = channel.getMaxFrequency() > getMaxTunedFrequency();
|
|
|
|
( ( mMiddleUnusable == 0 ) ||
|
|
|
|
boolean overlapsCenter = mMiddleUnusable > 0 &&
|
|
|
|
( !channel.overlaps( getTunedFrequency() - mMiddleUnusable,
|
|
|
|
channel.overlaps(getFrequency() - mMiddleUnusable, getFrequency() + mMiddleUnusable);
|
|
|
|
getTunedFrequency() + mMiddleUnusable ) ) ) );
|
|
|
|
|
|
|
|
|
|
|
|
return isAbove || isBelow || overlapsCenter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Releases the currently sourced tuner channel from this tuner and shuts
|
|
|
|
* Releases the currently sourced tuner channel from this tuner and shuts down the tuner if no other sources exist.
|
|
|
|
* down the tuner if no other sources exist.
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void releaseChannel(TunerChannelSource tunerChannelSource)
|
|
|
|
public void releaseChannel(TunerChannelSource tunerChannelSource)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -271,82 +252,79 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Sets the Local Oscillator frequency accomodate the current set of tuned
|
|
|
|
* Sets the Local Oscillator frequency to accomodate the current set of tuned channels.
|
|
|
|
* channels.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* If there is only a single tuned channel, it is placed immediately to the
|
|
|
|
* If there is only a single tuned channel, it is placed immediately to the right of the usable bandwidth right
|
|
|
|
* right of the usable bandwidth right of the central DC spike.
|
|
|
|
* of the central DC spike.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Otherwise, it places the highest channel frequency at the upper end of
|
|
|
|
* Otherwise, it places the highest channel frequency at the upper end of the tuner bandwidth, and then iteratively
|
|
|
|
* the tuner bandwidth, and then iteratively moves the center frequency
|
|
|
|
* moves the center frequency higher until all channels fit within the bandwidth and none of the channels overlap
|
|
|
|
* higher until all channels fit within the bandwidth and none of the
|
|
|
|
* any defined central DC spike unusable region. If a center tune frequency cannot be calculated, throw an
|
|
|
|
* channels overlap any defined central DC spike unusable region. If a
|
|
|
|
* exception so that the most recently added channel can be removed.
|
|
|
|
* center tune frequency cannot be calculated, throw an exception so that
|
|
|
|
|
|
|
|
* the most recently added channel can be removed.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Note: the tuned frequency is not changed until a legitimate new frequency
|
|
|
|
* Note: the tuned frequency is not changed until a legitimate new frequency can be calculated. If an exception
|
|
|
|
* can be calculated. If an exception is thrown, the current frequency is
|
|
|
|
* is thrown, the current frequency is retained, so that the recently added channel can be removed and all other
|
|
|
|
* retained, so that the recently added channel can be removed and all other
|
|
|
|
|
|
|
|
* channels can continue as previously arranged.
|
|
|
|
* channels can continue as previously arranged.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @throws SourceException if the set of tuner channels, including a recently
|
|
|
|
* @throws SourceException if the set of tuner channels, including a recently added channel, cannot be tuned
|
|
|
|
* added channel, cannot be tuned within the current tuner bandwidth and any
|
|
|
|
* within the current tuner bandwidth and any central DC spike unusable region.
|
|
|
|
* central DC spike unusable region.
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private void updateLOFrequency() throws SourceException
|
|
|
|
private void updateLOFrequency() throws SourceException
|
|
|
|
{
|
|
|
|
{
|
|
|
|
long frequency = getFrequency();
|
|
|
|
long candidateFrequency;
|
|
|
|
|
|
|
|
|
|
|
|
boolean frequencyValid = true;
|
|
|
|
boolean isValidCandidateFrequency = true;
|
|
|
|
|
|
|
|
|
|
|
|
//If there is only 1 channel, position it to the right of center
|
|
|
|
//If there is only 1 channel set the center frequency so that the channel is positioned to the right of center
|
|
|
|
if(mTunedChannels.size() == 1)
|
|
|
|
if(mTunedChannels.size() == 1)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
frequency = mTunedChannels.first().getMinFrequency() - mMiddleUnusable;
|
|
|
|
candidateFrequency = mTunedChannels.first().getMinFrequency() - mMiddleUnusable + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
long minLockedFrequency = mTunedChannels.first().getMinFrequency();
|
|
|
|
long minLockedFrequency = mTunedChannels.first().getMinFrequency();
|
|
|
|
long maxLockedFrequency = mTunedChannels.last().getMaxFrequency();
|
|
|
|
long maxLockedFrequency = mTunedChannels.last().getMaxFrequency();
|
|
|
|
|
|
|
|
|
|
|
|
//Start by placing the highest frequency channel at the high end of
|
|
|
|
//Start by placing the highest frequency channel at the high end of the spectrum
|
|
|
|
//the spectrum
|
|
|
|
candidateFrequency = maxLockedFrequency - (getUsableBandwidth() / 2);
|
|
|
|
frequency = maxLockedFrequency - ( getUsableBandwidth() / 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Iterate the channels and make sure that none of them overlap the
|
|
|
|
//Iterate the channels and make sure that none of them overlap the center DC spike buffer, if one exists
|
|
|
|
//center DC spike buffer, if one exists
|
|
|
|
|
|
|
|
if(mMiddleUnusable > 0)
|
|
|
|
if(mMiddleUnusable > 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
boolean processingRequired = true;
|
|
|
|
boolean processingRequired = true;
|
|
|
|
|
|
|
|
|
|
|
|
while( frequencyValid && processingRequired )
|
|
|
|
while(isValidCandidateFrequency && processingRequired)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
processingRequired = false;
|
|
|
|
processingRequired = false;
|
|
|
|
|
|
|
|
|
|
|
|
long minAvoid = frequency - mMiddleUnusable;
|
|
|
|
long minAvoid = candidateFrequency - mMiddleUnusable;
|
|
|
|
long maxAvoid = frequency + mMiddleUnusable;
|
|
|
|
long maxAvoid = candidateFrequency + mMiddleUnusable;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//If any of the center channel(s) overlap the central DC spike avoid area, we'll iteratively
|
|
|
|
|
|
|
|
//increase the tuned frequency causing the set of channels to move left in the tuned bandwidth until
|
|
|
|
|
|
|
|
//we either find a good center tune frequency, or we walk the lowest frequency channel out of the
|
|
|
|
|
|
|
|
//minimum tuned range, in which case we'll throw an exception indicating we don't have a solution.
|
|
|
|
for(TunerChannel channel : mTunedChannels)
|
|
|
|
for(TunerChannel channel : mTunedChannels)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(channel.overlaps(minAvoid, maxAvoid))
|
|
|
|
if(channel.overlaps(minAvoid, maxAvoid))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
//Can we move the frequency lower so that the
|
|
|
|
//Calculate a tuned frequency adjustment that places this overlapping channel just to the
|
|
|
|
//channel sits to the right of center?
|
|
|
|
//left of the central DC spike avoid zone
|
|
|
|
long adjustment = channel.getMaxFrequency() - minAvoid;
|
|
|
|
long adjustment = channel.getMaxFrequency() - minAvoid + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if( frequency + adjustment -
|
|
|
|
//If the candidate frequency doesn't push the lowest channel out of bounds, make adjustment
|
|
|
|
( getUsableBandwidth() / 2 ) <= minLockedFrequency )
|
|
|
|
if(candidateFrequency + adjustment - (getUsableBandwidth() / 2) <= minLockedFrequency)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
frequency += adjustment;
|
|
|
|
candidateFrequency += adjustment;
|
|
|
|
processingRequired = true;
|
|
|
|
processingRequired = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Otherwise, punt and indicate that we can't find a center frequency or add the channel
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
frequencyValid = false;
|
|
|
|
isValidCandidateFrequency = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//break out of the for/each loop, so that we can
|
|
|
|
//break out of the for/each loop, so that we can start over again with all of the channels
|
|
|
|
//start over again with all of the channels
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -354,20 +332,18 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( frequencyValid )
|
|
|
|
if(isValidCandidateFrequency)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
mFrequencyController.setFrequency( frequency );
|
|
|
|
mFrequencyController.setFrequency(candidateFrequency);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
throw new SourceException( "Couldn't calculate viable center "
|
|
|
|
throw new SourceException("Couldn't calculate viable center frequency from set of tuner channels");
|
|
|
|
+ "frequency from set of tuner channels" );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Usable bandwidth - total bandwidth minus the unusable space at either end
|
|
|
|
* Usable bandwidth - total bandwidth minus the unusable space at either end of the spectrum.
|
|
|
|
* of the spectrum.
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private int getUsableBandwidth()
|
|
|
|
private int getUsableBandwidth()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@@ -375,11 +351,9 @@ public abstract class TunerController implements Tunable, IFrequencyChangeProces
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Sets the listener to be notified any time that the tuner changes frequency
|
|
|
|
* Sets the listener to be notified any time that the tuner changes frequency or bandwidth/sample rate.
|
|
|
|
* or bandwidth/sample rate.
|
|
|
|
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Note: this is normally used by the Tuner. Any additional listeners can
|
|
|
|
* Note: this is normally used by the Tuner. Any additional listeners can be registered on the tuner.
|
|
|
|
* be registered on the tuner.
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void addListener(IFrequencyChangeProcessor processor)
|
|
|
|
public void addListener(IFrequencyChangeProcessor processor)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|