mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 09:07:27 -05:00
Compare commits
11 Commits
v0.2.0-bet
...
v0.2.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
daf2b58cf2 | ||
|
|
cf2c0ca07d | ||
|
|
eead22ffad | ||
|
|
1550c62782 | ||
|
|
5f2d8c8fe6 | ||
|
|
22d3871d0b | ||
|
|
455e45269c | ||
|
|
ca8406bdc0 | ||
|
|
399d164bd0 | ||
|
|
6f2a7e89a9 | ||
|
|
b821588e54 |
@@ -7,7 +7,7 @@
|
|||||||
<property name="major" value="0"/>
|
<property name="major" value="0"/>
|
||||||
<property name="minor" value="2"/>
|
<property name="minor" value="2"/>
|
||||||
<property name="patch" value="0"/>
|
<property name="patch" value="0"/>
|
||||||
<property name="release" value="beta.7"/>
|
<property name="release" value="beta.8"/>
|
||||||
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}-${release}"/>
|
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}-${release}"/>
|
||||||
|
|
||||||
<!-- Build properties -->
|
<!-- Build properties -->
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ public class ChannelStatePanel extends JPanel
|
|||||||
switch( changedAttribute )
|
switch( changedAttribute )
|
||||||
{
|
{
|
||||||
case CHANNEL_STATE:
|
case CHANNEL_STATE:
|
||||||
if( state.getState() != null )
|
if( state != null && state.getState() != null )
|
||||||
{
|
{
|
||||||
mStateLabel.setText( state.getState().getDisplayValue() );
|
mStateLabel.setText( state.getState().getDisplayValue() );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ public class TrafficChannelManager extends Module
|
|||||||
@Override
|
@Override
|
||||||
public void dispose()
|
public void dispose()
|
||||||
{
|
{
|
||||||
mLog.debug( "dispose() on traffic channel manager" );
|
|
||||||
for( Channel trafficChannel: mTrafficChannelPool )
|
for( Channel trafficChannel: mTrafficChannelPool )
|
||||||
{
|
{
|
||||||
trafficChannel.setEnabled( false );
|
trafficChannel.setEnabled( false );
|
||||||
|
|||||||
@@ -557,11 +557,6 @@ public class SettingsManager
|
|||||||
ArrayList<TunerConfiguration> configs = getSettings()
|
ArrayList<TunerConfiguration> configs = getSettings()
|
||||||
.getTunerConfigurations( type );
|
.getTunerConfigurations( type );
|
||||||
|
|
||||||
if( configs.isEmpty() )
|
|
||||||
{
|
|
||||||
configs.add( addNewTunerConfiguration( type, "Default" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
return configs;
|
return configs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -544,16 +544,14 @@ public class TunerManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
config = configs.get( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
//If we're still null at this point, create a default config
|
//If we're still null at this point, create a default config
|
||||||
if( config == null )
|
if( config == null )
|
||||||
{
|
{
|
||||||
|
String name = "Default-" + tuner.getUniqueID();
|
||||||
|
|
||||||
config = mResourceManager.getSettingsManager()
|
config = mResourceManager.getSettingsManager()
|
||||||
.addNewTunerConfiguration( tuner.getTunerType(), "Default" );
|
.addNewTunerConfiguration( tuner.getTunerType(), name );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Persist the config as the selected tuner configuration. The method
|
//Persist the config as the selected tuner configuration. The method
|
||||||
|
|||||||
@@ -262,7 +262,30 @@ public class AirspyTunerController extends TunerController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static String getTransferStatus( int status )
|
||||||
|
{
|
||||||
|
switch( status )
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "TRANSFER COMPLETED (0)";
|
||||||
|
case 1:
|
||||||
|
return "TRANSFER ERROR (1)";
|
||||||
|
case 2:
|
||||||
|
return "TRANSFER TIMED OUT (2)";
|
||||||
|
case 3:
|
||||||
|
return "TRANSFER CANCELLED (3)";
|
||||||
|
case 4:
|
||||||
|
return "TRANSFER STALL (4)";
|
||||||
|
case 5:
|
||||||
|
return "TRANSFER NO DEVICE (5)";
|
||||||
|
case 6:
|
||||||
|
return "TRANSFER OVERFLOW (6)";
|
||||||
|
default:
|
||||||
|
return "UNKNOWN TRANSFER STATUS (" + status + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void apply( TunerConfiguration config ) throws SourceException
|
public void apply( TunerConfiguration config ) throws SourceException
|
||||||
{
|
{
|
||||||
if( config instanceof AirspyTunerConfiguration )
|
if( config instanceof AirspyTunerConfiguration )
|
||||||
@@ -1192,18 +1215,21 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void addListener( Listener<ComplexBuffer> listener )
|
public void addListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.addListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.addListener( listener );
|
||||||
|
|
||||||
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
||||||
{
|
{
|
||||||
mBufferProcessor = new BufferProcessor();
|
mBufferProcessor = new BufferProcessor();
|
||||||
|
|
||||||
Thread thread = new Thread( mBufferProcessor );
|
Thread thread = new Thread( mBufferProcessor );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.setName( "Airspy Buffer Processor" );
|
thread.setName( "Airspy Buffer Processor" );
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1212,12 +1238,15 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void removeListener( Listener<ComplexBuffer> listener )
|
public void removeListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.removeListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.removeListener( listener );
|
||||||
|
|
||||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||||
{
|
{
|
||||||
mBufferProcessor.stop();
|
mBufferProcessor.stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1227,8 +1256,11 @@ public class AirspyTunerController extends TunerController
|
|||||||
public class BufferProcessor implements Runnable, TransferCallback
|
public class BufferProcessor implements Runnable, TransferCallback
|
||||||
{
|
{
|
||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
|
private boolean mCancel = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
@@ -1237,33 +1269,64 @@ public class AirspyTunerController extends TunerController
|
|||||||
{
|
{
|
||||||
prepareTransfers();
|
prepareTransfers();
|
||||||
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error submitting transfer [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
||||||
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
||||||
20, TimeUnit.MILLISECONDS );
|
20, TimeUnit.MILLISECONDS );
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||||
|
|
||||||
|
List<Transfer> transfers = new ArrayList<>();
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
|
||||||
while( mRunning.get() )
|
while( mRunning.get() )
|
||||||
{
|
{
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
mAvailableTransfers.drainTo( transfers );
|
||||||
|
|
||||||
|
for( Transfer transfer: transfers )
|
||||||
|
{
|
||||||
|
int result = LibUsb.submitTransfer( transfer );
|
||||||
|
|
||||||
|
if( result == LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mTransfersInProgress.add( transfer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "error submitting transfer [" +
|
||||||
|
LibUsb.errorName( result ) + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
null, USB_TIMEOUT_MS, completed.asIntBuffer() );
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
if( result != LibUsb.SUCCESS )
|
||||||
{
|
{
|
||||||
mLog.error( "error handling events for libusb" );
|
mLog.error( "error handling events for libusb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfers.clear();
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mCancel )
|
||||||
|
{
|
||||||
|
for( Transfer transfer: mTransfersInProgress )
|
||||||
|
{
|
||||||
|
LibUsb.cancelTransfer( transfer );
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = LibUsb.handleEventsTimeoutCompleted( null,
|
||||||
|
USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
|
if( result != LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mLog.error( "error handling events for libusb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1273,10 +1336,10 @@ public class AirspyTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mCancel = true;
|
||||||
|
|
||||||
if( mRunning.compareAndSet( true, false ) )
|
if( mRunning.compareAndSet( true, false ) )
|
||||||
{
|
{
|
||||||
cancel();
|
|
||||||
|
|
||||||
if( mSampleDispatcherTask != null )
|
if( mSampleDispatcherTask != null )
|
||||||
{
|
{
|
||||||
mSampleDispatcherTask.cancel( true );
|
mSampleDispatcherTask.cancel( true );
|
||||||
@@ -1296,97 +1359,68 @@ public class AirspyTunerController extends TunerController
|
|||||||
@Override
|
@Override
|
||||||
public void processTransfer( Transfer transfer )
|
public void processTransfer( Transfer transfer )
|
||||||
{
|
{
|
||||||
if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
|
mTransfersInProgress.remove( transfer );
|
||||||
{
|
|
||||||
ByteBuffer buffer = transfer.buffer();
|
|
||||||
|
|
||||||
byte[] data = new byte[ transfer.actualLength() ];
|
|
||||||
|
|
||||||
buffer.get( data );
|
|
||||||
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
mFilledBuffers.add( data );
|
|
||||||
|
|
||||||
if( !isRunning() )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( transfer.status() )
|
switch( transfer.status() )
|
||||||
{
|
{
|
||||||
case LibUsb.TRANSFER_COMPLETED:
|
case LibUsb.TRANSFER_COMPLETED:
|
||||||
/* resubmit the transfer */
|
case LibUsb.TRANSFER_STALL:
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
if( transfer.actualLength() > 0 )
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
{
|
||||||
mLog.error( "couldn't resubmit buffer transfer to tuner" );
|
ByteBuffer buffer = transfer.buffer();
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
byte[] data = new byte[ transfer.actualLength() ];
|
||||||
|
|
||||||
|
buffer.get( data );
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
if( isRunning() )
|
||||||
|
{
|
||||||
|
mFilledBuffers.add( data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LibUsb.TRANSFER_CANCELLED:
|
case LibUsb.TRANSFER_CANCELLED:
|
||||||
/* free the transfer and remove it */
|
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected error */
|
/* unexpected error */
|
||||||
mLog.error( "transfer error" );
|
mLog.error( "transfer error [" +
|
||||||
|
getTransferStatus( transfer.status() ) +
|
||||||
|
"] transferred actual: " + transfer.actualLength() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancel()
|
|
||||||
{
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
|
||||||
null, USB_TIMEOUT_MS, completed.asIntBuffer() );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error handling usb events during cancel [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares (allocates) a set of transfer buffers for use in
|
* Prepares (allocates) a set of transfer buffers for use in
|
||||||
* transferring data from the tuner via the bulk interface
|
* transferring data from the tuner via the bulk interface
|
||||||
*/
|
*/
|
||||||
private void prepareTransfers() throws LibUsbException
|
private void prepareTransfers() throws LibUsbException
|
||||||
{
|
{
|
||||||
mTransfers = new CopyOnWriteArrayList<Transfer>();
|
if( mAvailableTransfers == null )
|
||||||
|
|
||||||
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
|
||||||
{
|
{
|
||||||
Transfer transfer = LibUsb.allocTransfer();
|
mAvailableTransfers = new LinkedTransferQueue<>();
|
||||||
|
|
||||||
if( transfer == null )
|
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
||||||
{
|
{
|
||||||
throw new LibUsbException( "couldn't allocate transfer",
|
Transfer transfer = LibUsb.allocTransfer();
|
||||||
LibUsb.ERROR_NO_MEM );
|
|
||||||
}
|
|
||||||
|
|
||||||
final ByteBuffer buffer =
|
if( transfer == null )
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
{
|
||||||
|
throw new LibUsbException( "couldn't allocate transfer",
|
||||||
|
LibUsb.ERROR_NO_MEM );
|
||||||
|
}
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer,
|
final ByteBuffer buffer =
|
||||||
mDeviceHandle,
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
USB_ENDPOINT,
|
|
||||||
buffer,
|
|
||||||
BufferProcessor.this,
|
|
||||||
"Buffer #" + x,
|
|
||||||
USB_TIMEOUT_MS );
|
|
||||||
|
|
||||||
mTransfers.add( transfer );
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle, USB_ENDPOINT,
|
||||||
|
buffer, BufferProcessor.this, "Buffer", USB_TIMEOUT_MS );
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.LinkedTransferQueue;
|
import java.util.concurrent.LinkedTransferQueue;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
@@ -91,7 +92,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
private final static Logger mLog =
|
private final static Logger mLog =
|
||||||
LoggerFactory.getLogger( HackRFTunerController.class );
|
LoggerFactory.getLogger( HackRFTunerController.class );
|
||||||
|
|
||||||
public final static long TIMEOUT_US = 1000000l; //uSeconds
|
public final static long USB_TIMEOUT_MS = 1000000l; //uSeconds
|
||||||
public static final byte USB_ENDPOINT = (byte)0x81;
|
public static final byte USB_ENDPOINT = (byte)0x81;
|
||||||
public static final byte USB_INTERFACE = (byte)0x0;
|
public static final byte USB_INTERFACE = (byte)0x0;
|
||||||
|
|
||||||
@@ -394,7 +395,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
(short)value,
|
(short)value,
|
||||||
(short)index,
|
(short)index,
|
||||||
buffer,
|
buffer,
|
||||||
TIMEOUT_US );
|
USB_TIMEOUT_MS );
|
||||||
|
|
||||||
if( transferred < 0 )
|
if( transferred < 0 )
|
||||||
{
|
{
|
||||||
@@ -467,7 +468,7 @@ public class HackRFTunerController extends TunerController
|
|||||||
(short)value,
|
(short)value,
|
||||||
(short)index,
|
(short)index,
|
||||||
buffer,
|
buffer,
|
||||||
TIMEOUT_US );
|
USB_TIMEOUT_MS );
|
||||||
|
|
||||||
if( transferred < 0 )
|
if( transferred < 0 )
|
||||||
{
|
{
|
||||||
@@ -886,18 +887,21 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void addListener( Listener<ComplexBuffer> listener )
|
public void addListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.addListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.addListener( listener );
|
||||||
|
|
||||||
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
if( mBufferProcessor == null || !mBufferProcessor.isRunning() )
|
||||||
{
|
{
|
||||||
mBufferProcessor = new BufferProcessor();
|
mBufferProcessor = new BufferProcessor();
|
||||||
|
|
||||||
Thread thread = new Thread( mBufferProcessor );
|
Thread thread = new Thread( mBufferProcessor );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.setName( "HackRF Sample Processor" );
|
thread.setName( "HackRF Sample Processor" );
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -906,12 +910,15 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void removeListener( Listener<ComplexBuffer> listener )
|
public void removeListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.removeListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.removeListener( listener );
|
||||||
|
|
||||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||||
{
|
{
|
||||||
mBufferProcessor.stop();
|
mBufferProcessor.stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -921,45 +928,77 @@ public class HackRFTunerController extends TunerController
|
|||||||
public class BufferProcessor implements Runnable, TransferCallback
|
public class BufferProcessor implements Runnable, TransferCallback
|
||||||
{
|
{
|
||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
|
private boolean mCancel = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
if( mRunning.compareAndSet( false, true ) )
|
if( mRunning.compareAndSet( false, true ) )
|
||||||
{
|
{
|
||||||
mLog.info( "starting HackRF sample fetch thread" );
|
|
||||||
|
|
||||||
prepareTransfers();
|
prepareTransfers();
|
||||||
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error submitting transfer [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
||||||
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
ThreadType.SOURCE_SAMPLE_PROCESSING, new BufferDispatcher(),
|
||||||
20, TimeUnit.MILLISECONDS );
|
20, TimeUnit.MILLISECONDS );
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||||
|
|
||||||
|
List<Transfer> transfers = new ArrayList<>();
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
|
||||||
while( mRunning.get() )
|
while( mRunning.get() )
|
||||||
{
|
{
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
mAvailableTransfers.drainTo( transfers );
|
||||||
|
|
||||||
|
for( Transfer transfer: transfers )
|
||||||
|
{
|
||||||
|
int result = LibUsb.submitTransfer( transfer );
|
||||||
|
|
||||||
|
if( result == LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mTransfersInProgress.add( transfer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "error submitting transfer [" +
|
||||||
|
LibUsb.errorName( result ) + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
if( result != LibUsb.SUCCESS )
|
||||||
{
|
{
|
||||||
mLog.error( "error handling events for libusb" );
|
mLog.error( "error handling events for libusb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfers.clear();
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( mCancel )
|
||||||
|
{
|
||||||
|
for( Transfer transfer: mTransfersInProgress )
|
||||||
|
{
|
||||||
|
LibUsb.cancelTransfer( transfer );
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
|
null, USB_TIMEOUT_MS, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
|
if( result != LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mLog.error( "error cancelling transfers in progress" );
|
||||||
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -969,12 +1008,10 @@ public class HackRFTunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mCancel = true;
|
||||||
|
|
||||||
if( mRunning.compareAndSet( true, false ) )
|
if( mRunning.compareAndSet( true, false ) )
|
||||||
{
|
{
|
||||||
mLog.info( "stopping HackRF sample fetch thread" );
|
|
||||||
|
|
||||||
cancel();
|
|
||||||
|
|
||||||
if( mSampleDispatcherTask != null )
|
if( mSampleDispatcherTask != null )
|
||||||
{
|
{
|
||||||
mSampleDispatcherTask.cancel( true );
|
mSampleDispatcherTask.cancel( true );
|
||||||
@@ -994,41 +1031,29 @@ public class HackRFTunerController extends TunerController
|
|||||||
@Override
|
@Override
|
||||||
public void processTransfer( Transfer transfer )
|
public void processTransfer( Transfer transfer )
|
||||||
{
|
{
|
||||||
if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
|
mTransfersInProgress.remove( transfer );
|
||||||
{
|
|
||||||
ByteBuffer buffer = transfer.buffer();
|
|
||||||
|
|
||||||
byte[] data = new byte[ transfer.actualLength() ];
|
|
||||||
|
|
||||||
buffer.get( data );
|
|
||||||
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
mFilledBuffers.add( data );
|
|
||||||
|
|
||||||
if( !isRunning() )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( transfer.status() )
|
switch( transfer.status() )
|
||||||
{
|
{
|
||||||
case LibUsb.TRANSFER_COMPLETED:
|
case LibUsb.TRANSFER_COMPLETED:
|
||||||
/* resubmit the transfer */
|
case LibUsb.TRANSFER_STALL:
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
if( transfer.actualLength() > 0 )
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
{
|
||||||
mLog.error( "couldn't resubmit buffer transfer to tuner" );
|
ByteBuffer buffer = transfer.buffer();
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
byte[] data = new byte[ transfer.actualLength() ];
|
||||||
|
|
||||||
|
buffer.get( data );
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
if( isRunning() )
|
||||||
|
{
|
||||||
|
mFilledBuffers.add( data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LibUsb.TRANSFER_CANCELLED:
|
case LibUsb.TRANSFER_CANCELLED:
|
||||||
/* free the transfer and remove it */
|
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected error */
|
/* unexpected error */
|
||||||
@@ -1036,57 +1061,38 @@ public class HackRFTunerController extends TunerController
|
|||||||
getTransferStatus( transfer.status() ) +
|
getTransferStatus( transfer.status() ) +
|
||||||
"] transferred actual: " + transfer.actualLength() );
|
"] transferred actual: " + transfer.actualLength() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancel()
|
|
||||||
{
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error handling usb events during cancel [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares (allocates) a set of transfer buffers for use in
|
* Prepares (allocates) a set of transfer buffers for use in
|
||||||
* transferring data from the tuner via the bulk interface
|
* transferring data from the tuner via the bulk interface
|
||||||
*/
|
*/
|
||||||
private void prepareTransfers() throws LibUsbException
|
private void prepareTransfers() throws LibUsbException
|
||||||
{
|
{
|
||||||
mTransfers = new CopyOnWriteArrayList<Transfer>();
|
if( mAvailableTransfers == null )
|
||||||
|
|
||||||
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
|
||||||
{
|
{
|
||||||
Transfer transfer = LibUsb.allocTransfer();
|
mAvailableTransfers = new LinkedTransferQueue<>();
|
||||||
|
|
||||||
if( transfer == null )
|
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
||||||
{
|
{
|
||||||
throw new LibUsbException( "couldn't allocate transfer",
|
Transfer transfer = LibUsb.allocTransfer();
|
||||||
LibUsb.ERROR_NO_MEM );
|
|
||||||
}
|
|
||||||
|
|
||||||
final ByteBuffer buffer =
|
if( transfer == null )
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
{
|
||||||
|
throw new LibUsbException( "couldn't allocate transfer",
|
||||||
|
LibUsb.ERROR_NO_MEM );
|
||||||
|
}
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer,
|
final ByteBuffer buffer =
|
||||||
mDeviceHandle,
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
USB_ENDPOINT,
|
|
||||||
buffer,
|
|
||||||
BufferProcessor.this,
|
|
||||||
"Buffer #" + x,
|
|
||||||
TIMEOUT_US );
|
|
||||||
|
|
||||||
mTransfers.add( transfer );
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle,USB_ENDPOINT,
|
||||||
|
buffer, BufferProcessor.this, "Buffer", USB_TIMEOUT_MS );
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import java.nio.charset.Charset;
|
|||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.List;
|
||||||
import java.util.concurrent.LinkedTransferQueue;
|
import java.util.concurrent.LinkedTransferQueue;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@@ -55,8 +55,6 @@ import sample.complex.ComplexBuffer;
|
|||||||
import source.SourceException;
|
import source.SourceException;
|
||||||
import source.tuner.TunerController;
|
import source.tuner.TunerController;
|
||||||
import source.tuner.TunerType;
|
import source.tuner.TunerType;
|
||||||
import source.tuner.frequency.FrequencyChangeEvent;
|
|
||||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
|
||||||
import buffer.FloatAveragingBuffer;
|
import buffer.FloatAveragingBuffer;
|
||||||
import controller.ResourceManager;
|
import controller.ResourceManager;
|
||||||
import controller.ThreadPoolManager;
|
import controller.ThreadPoolManager;
|
||||||
@@ -73,7 +71,7 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
public final static int TWO_TO_22_POWER = 4194304;
|
public final static int TWO_TO_22_POWER = 4194304;
|
||||||
|
|
||||||
public final static byte USB_INTERFACE = (byte)0x0;
|
public final static byte USB_INTERFACE = (byte)0x0;
|
||||||
public final static byte BULK_ENDPOINT_IN = (byte)0x81;
|
public final static byte USB_BULK_ENDPOINT = (byte)0x81;
|
||||||
public final static byte CONTROL_ENDPOINT_IN =
|
public final static byte CONTROL_ENDPOINT_IN =
|
||||||
(byte)( LibUsb.ENDPOINT_IN | LibUsb.REQUEST_TYPE_VENDOR );
|
(byte)( LibUsb.ENDPOINT_IN | LibUsb.REQUEST_TYPE_VENDOR );
|
||||||
public final static byte CONTROL_ENDPOINT_OUT =
|
public final static byte CONTROL_ENDPOINT_OUT =
|
||||||
@@ -1342,21 +1340,24 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void addListener( Listener<ComplexBuffer> listener )
|
public void addListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.addListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.addListener( listener );
|
||||||
|
|
||||||
if( mBufferProcessor == null )
|
if( mBufferProcessor == null )
|
||||||
{
|
{
|
||||||
mBufferProcessor = new BufferProcessor( mThreadPoolManager );
|
mBufferProcessor = new BufferProcessor( mThreadPoolManager );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !mBufferProcessor.isRunning() )
|
if( !mBufferProcessor.isRunning() )
|
||||||
{
|
{
|
||||||
Thread thread = new Thread( mBufferProcessor );
|
Thread thread = new Thread( mBufferProcessor );
|
||||||
thread.setDaemon( true );
|
thread.setDaemon( true );
|
||||||
thread.setName( "RTL2832 Sample Processor" );
|
thread.setName( "RTL2832 Sample Processor" );
|
||||||
|
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1365,12 +1366,15 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void removeListener( Listener<ComplexBuffer> listener )
|
public void removeListener( Listener<ComplexBuffer> listener )
|
||||||
{
|
{
|
||||||
mComplexBufferBroadcaster.removeListener( listener );
|
synchronized( mComplexBufferBroadcaster )
|
||||||
|
{
|
||||||
|
mComplexBufferBroadcaster.removeListener( listener );
|
||||||
|
|
||||||
if( !mComplexBufferBroadcaster.hasListeners() )
|
if( !mComplexBufferBroadcaster.hasListeners() )
|
||||||
{
|
{
|
||||||
mBufferProcessor.stop();
|
mBufferProcessor.stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1380,9 +1384,12 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
public class BufferProcessor implements Runnable, TransferCallback
|
public class BufferProcessor implements Runnable, TransferCallback
|
||||||
{
|
{
|
||||||
private ScheduledFuture<?> mSampleDispatcherTask;
|
private ScheduledFuture<?> mSampleDispatcherTask;
|
||||||
private CopyOnWriteArrayList<Transfer> mTransfers;
|
private LinkedTransferQueue<Transfer> mAvailableTransfers;
|
||||||
|
private LinkedTransferQueue<Transfer> mTransfersInProgress = new LinkedTransferQueue<>();
|
||||||
private AtomicBoolean mRunning = new AtomicBoolean();
|
private AtomicBoolean mRunning = new AtomicBoolean();
|
||||||
private ThreadPoolManager mThreadPoolManager;
|
private ThreadPoolManager mThreadPoolManager;
|
||||||
|
private ByteBuffer mLibUsbHandlerStatus;
|
||||||
|
private boolean mCancel = false;
|
||||||
|
|
||||||
public BufferProcessor( ThreadPoolManager manager )
|
public BufferProcessor( ThreadPoolManager manager )
|
||||||
{
|
{
|
||||||
@@ -1409,18 +1416,6 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
|
|
||||||
prepareTransfers();
|
prepareTransfers();
|
||||||
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error submitting transfer [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
mSampleDispatcherTask = mThreadPoolManager.scheduleFixedRate(
|
||||||
@@ -1432,19 +1427,65 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
mLog.error( "NPE! = tpm null: " + ( mThreadPoolManager == null ), npe );
|
mLog.error( "NPE! = tpm null: " + ( mThreadPoolManager == null ), npe );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus = ByteBuffer.allocateDirect( 4 );
|
||||||
|
|
||||||
while( mRunning.get() )
|
List<Transfer> transfers = new ArrayList<>();
|
||||||
|
|
||||||
|
mCancel = false;
|
||||||
|
|
||||||
|
while( mRunning.get() )
|
||||||
{
|
{
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
mAvailableTransfers.drainTo( transfers );
|
||||||
|
|
||||||
|
for( Transfer transfer: transfers )
|
||||||
|
{
|
||||||
|
int result = LibUsb.submitTransfer( transfer );
|
||||||
|
|
||||||
|
if( result == LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mTransfersInProgress.add( transfer );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "Error submitting transfer [" +
|
||||||
|
LibUsb.errorName( result ) + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
null, TIMEOUT_US, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
if( result != LibUsb.SUCCESS )
|
||||||
{
|
{
|
||||||
mLog.error( "error handling events for libusb" );
|
mLog.error( "error handling events for libusb" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transfers.clear();
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( mCancel )
|
||||||
|
{
|
||||||
|
for( Transfer transfer: mTransfersInProgress )
|
||||||
|
{
|
||||||
|
LibUsb.cancelTransfer( transfer );
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = LibUsb.handleEventsTimeoutCompleted(
|
||||||
|
null, TIMEOUT_US, mLibUsbHandlerStatus.asIntBuffer() );
|
||||||
|
|
||||||
|
if( result != LibUsb.SUCCESS )
|
||||||
|
{
|
||||||
|
mLog.error( "error handling events for libusb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
mLibUsbHandlerStatus.rewind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mLog.error( "Couldn't start buffer processor - already running!" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1453,10 +1494,10 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
*/
|
*/
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
|
mCancel = true;
|
||||||
|
|
||||||
if( mRunning.compareAndSet( true, false ) )
|
if( mRunning.compareAndSet( true, false ) )
|
||||||
{
|
{
|
||||||
cancel();
|
|
||||||
|
|
||||||
if( mSampleDispatcherTask != null )
|
if( mSampleDispatcherTask != null )
|
||||||
{
|
{
|
||||||
mThreadPoolManager.cancel( mSampleDispatcherTask );
|
mThreadPoolManager.cancel( mSampleDispatcherTask );
|
||||||
@@ -1477,43 +1518,29 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
@Override
|
@Override
|
||||||
public void processTransfer( Transfer transfer )
|
public void processTransfer( Transfer transfer )
|
||||||
{
|
{
|
||||||
if( transfer.status() == LibUsb.TRANSFER_COMPLETED )
|
mTransfersInProgress.remove( transfer );
|
||||||
{
|
|
||||||
ByteBuffer buffer = transfer.buffer();
|
|
||||||
|
|
||||||
byte[] data = new byte[ transfer.actualLength() ];
|
|
||||||
|
|
||||||
buffer.get( data );
|
|
||||||
|
|
||||||
buffer.rewind();
|
|
||||||
|
|
||||||
mFilledBuffers.add( data );
|
|
||||||
|
|
||||||
mSampleCounter.addAndGet( transfer.actualLength() );
|
|
||||||
|
|
||||||
if( !isRunning() )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( transfer.status() )
|
switch( transfer.status() )
|
||||||
{
|
{
|
||||||
case LibUsb.TRANSFER_COMPLETED:
|
case LibUsb.TRANSFER_COMPLETED:
|
||||||
/* resubmit the transfer */
|
case LibUsb.TRANSFER_STALL:
|
||||||
int result = LibUsb.submitTransfer( transfer );
|
if( transfer.actualLength() > 0 )
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
{
|
||||||
mLog.error( "couldn't resubmit buffer transfer to tuner" );
|
ByteBuffer buffer = transfer.buffer();
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
byte[] data = new byte[ transfer.actualLength() ];
|
||||||
|
|
||||||
|
buffer.get( data );
|
||||||
|
|
||||||
|
buffer.rewind();
|
||||||
|
|
||||||
|
if( isRunning() )
|
||||||
|
{
|
||||||
|
mFilledBuffers.add( data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LibUsb.TRANSFER_CANCELLED:
|
case LibUsb.TRANSFER_CANCELLED:
|
||||||
/* free the transfer and remove it */
|
|
||||||
LibUsb.freeTransfer( transfer );
|
|
||||||
mTransfers.remove( transfer );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* unexpected error */
|
/* unexpected error */
|
||||||
@@ -1521,57 +1548,38 @@ public abstract class RTL2832TunerController extends TunerController
|
|||||||
getTransferStatus( transfer.status() ) +
|
getTransferStatus( transfer.status() ) +
|
||||||
"] transferred actual: " + transfer.actualLength() );
|
"] transferred actual: " + transfer.actualLength() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancel()
|
|
||||||
{
|
|
||||||
for( Transfer transfer: mTransfers )
|
|
||||||
{
|
|
||||||
LibUsb.cancelTransfer( transfer );
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer completed = ByteBuffer.allocateDirect( 4 );
|
|
||||||
|
|
||||||
int result = LibUsb.handleEventsTimeoutCompleted(
|
|
||||||
null, TIMEOUT_US, completed.asIntBuffer() );
|
|
||||||
|
|
||||||
if( result != LibUsb.SUCCESS )
|
|
||||||
{
|
|
||||||
mLog.error( "error handling usb events during cancel [" +
|
|
||||||
LibUsb.errorName( result ) + "]" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares (allocates) a set of transfer buffers for use in
|
* Prepares (allocates) a set of transfer buffers for use in
|
||||||
* transferring data from the tuner via the bulk interface
|
* transferring data from the tuner via the bulk interface
|
||||||
*/
|
*/
|
||||||
private void prepareTransfers() throws LibUsbException
|
private void prepareTransfers() throws LibUsbException
|
||||||
{
|
{
|
||||||
mTransfers = new CopyOnWriteArrayList<Transfer>();
|
if( mAvailableTransfers == null )
|
||||||
|
|
||||||
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
|
||||||
{
|
{
|
||||||
Transfer transfer = LibUsb.allocTransfer();
|
mAvailableTransfers = new LinkedTransferQueue<>();
|
||||||
|
|
||||||
if( transfer == null )
|
for( int x = 0; x < TRANSFER_BUFFER_POOL_SIZE; x++ )
|
||||||
{
|
{
|
||||||
throw new LibUsbException( "couldn't allocate transfer",
|
Transfer transfer = LibUsb.allocTransfer();
|
||||||
LibUsb.ERROR_NO_MEM );
|
|
||||||
}
|
|
||||||
|
|
||||||
final ByteBuffer buffer =
|
if( transfer == null )
|
||||||
ByteBuffer.allocateDirect( mBufferSize );
|
{
|
||||||
|
throw new LibUsbException( "couldn't allocate transfer",
|
||||||
|
LibUsb.ERROR_NO_MEM );
|
||||||
|
}
|
||||||
|
|
||||||
LibUsb.fillBulkTransfer( transfer,
|
final ByteBuffer buffer =
|
||||||
mDeviceHandle,
|
ByteBuffer.allocateDirect( mBufferSize );
|
||||||
BULK_ENDPOINT_IN,
|
|
||||||
buffer,
|
|
||||||
BufferProcessor.this,
|
|
||||||
"Buffer #" + x,
|
|
||||||
TIMEOUT_US );
|
|
||||||
|
|
||||||
mTransfers.add( transfer );
|
LibUsb.fillBulkTransfer( transfer, mDeviceHandle, USB_BULK_ENDPOINT,
|
||||||
|
buffer, BufferProcessor.this, "Buffer", TIMEOUT_US );
|
||||||
|
|
||||||
|
mAvailableTransfers.add( transfer );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class R820TTunerConfiguration extends TunerConfiguration
|
|||||||
private R820TLNAGain mLNAGain = R820TLNAGain.GAIN_222;
|
private R820TLNAGain mLNAGain = R820TLNAGain.GAIN_222;
|
||||||
private R820TVGAGain mVGAGain = R820TVGAGain.GAIN_210;
|
private R820TVGAGain mVGAGain = R820TVGAGain.GAIN_210;
|
||||||
private double mFrequencyCorrection = 0.0d;
|
private double mFrequencyCorrection = 0.0d;
|
||||||
private SampleRate mSampleRate = SampleRate.RATE_1_920MHZ;
|
private SampleRate mSampleRate = SampleRate.RATE_2_400MHZ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for JAXB
|
* Default constructor for JAXB
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package spectrum;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
@@ -56,8 +57,12 @@ public class DFTProcessor implements Listener<ComplexBuffer>,
|
|||||||
private CopyOnWriteArrayList<DFTResultsConverter> mListeners =
|
private CopyOnWriteArrayList<DFTResultsConverter> mListeners =
|
||||||
new CopyOnWriteArrayList<DFTResultsConverter>();
|
new CopyOnWriteArrayList<DFTResultsConverter>();
|
||||||
|
|
||||||
private ArrayBlockingQueue<ComplexBuffer> mQueue =
|
//Fixed size sample queue. We set the size at 12 based on the highest
|
||||||
new ArrayBlockingQueue<ComplexBuffer>( 200 );
|
//sample rate tuner (10 MHz) producing 153 frames per second and the lowest
|
||||||
|
//DFT processing frame rate of 12 frames per second. This means that the
|
||||||
|
//maximum size needed is 153 / 12 = 11 frames per DFT processing iteration
|
||||||
|
//so we set it at 12.
|
||||||
|
private BlockingQueue<ComplexBuffer> mQueue = new ArrayBlockingQueue<>( 12 );
|
||||||
|
|
||||||
private ScheduledExecutorService mScheduler = Executors
|
private ScheduledExecutorService mScheduler = Executors
|
||||||
.newScheduledThreadPool( 1, new NamingThreadFactory( "spectrum dft" ) );
|
.newScheduledThreadPool( 1, new NamingThreadFactory( "spectrum dft" ) );
|
||||||
@@ -246,15 +251,7 @@ public class DFTProcessor implements Listener<ComplexBuffer>,
|
|||||||
@Override
|
@Override
|
||||||
public void receive( ComplexBuffer sampleBuffer )
|
public void receive( ComplexBuffer sampleBuffer )
|
||||||
{
|
{
|
||||||
if( !mQueue.offer( sampleBuffer ) )
|
mQueue.offer( sampleBuffer );
|
||||||
{
|
|
||||||
mLog.error( "DFTProcessor - [" + mSampleType.toString()
|
|
||||||
+ "] queue is full, purging queue, "
|
|
||||||
+ "samples[" + sampleBuffer + "]" );
|
|
||||||
|
|
||||||
mQueue.clear();
|
|
||||||
mQueue.offer( sampleBuffer );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getNextBuffer()
|
private void getNextBuffer()
|
||||||
|
|||||||
Reference in New Issue
Block a user