mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 01:27:34 -05:00
Co-authored-by: denny <dennis.sheirer@gmail.com>
This commit is contained in:
@@ -124,8 +124,9 @@ dependencies {
|
|||||||
implementation 'com.mpatric:mp3agic:0.9.1'
|
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||||
implementation 'commons-io:commons-io:2.22.0'
|
implementation 'commons-io:commons-io:2.22.0'
|
||||||
implementation 'eu.hansolo:charts:1.0.5'
|
implementation 'eu.hansolo:charts:1.0.5'
|
||||||
implementation 'io.github.dsheirer:jbladerf:2.6.0' //bladeRF tuners - GitHub release, see settings.gradle
|
|
||||||
implementation 'io.github.dsheirer:jairspy:1.0.12' //Airspy tuners - GitHub release, see settings.gradle
|
implementation 'io.github.dsheirer:jairspy:1.0.12' //Airspy tuners - GitHub release, see settings.gradle
|
||||||
|
implementation 'io.github.dsheirer:jairspyhf:1.8.1' //Airspy HF+ tuners - GitHub release, see settings.gradle
|
||||||
|
implementation 'io.github.dsheirer:jbladerf:2.6.0' //bladeRF tuners - GitHub release, see settings.gradle
|
||||||
implementation 'io.github.dsheirer:jhydrasdr:1.1.4' //HydraSDR tuners - GitHub release, see settings.gradle
|
implementation 'io.github.dsheirer:jhydrasdr:1.1.4' //HydraSDR tuners - GitHub release, see settings.gradle
|
||||||
implementation 'io.github.dsheirer:jrtl:1.4.0.1' //RTL-SDR tuners - GitHub release, see settings.gradle
|
implementation 'io.github.dsheirer:jrtl:1.4.0.1' //RTL-SDR tuners - GitHub release, see settings.gradle
|
||||||
implementation 'io.github.dsheirer:radio-reference-api:18.0.0'
|
implementation 'io.github.dsheirer:radio-reference-api:18.0.0'
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ dependencyResolutionManagement {
|
|||||||
content { includeModule 'io.github.dsheirer', 'jairspy' }
|
content { includeModule 'io.github.dsheirer', 'jairspy' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//jAirspyHF is published as a GitHub release, with the native libraries for all platforms in the jar
|
||||||
|
ivy {
|
||||||
|
url = 'https://github.com/DSheirer/jAirspyHF/releases/download'
|
||||||
|
patternLayout { artifact 'v[revision]/[artifact]-[revision].[ext]' }
|
||||||
|
metadataSources { artifact() }
|
||||||
|
content { includeModule 'io.github.dsheirer', 'jairspyhf' }
|
||||||
|
}
|
||||||
|
|
||||||
//jRTL is published as a GitHub release, with the native libraries for all platforms in the jar
|
//jRTL is published as a GitHub release, with the native libraries for all platforms in the jar
|
||||||
ivy {
|
ivy {
|
||||||
url = 'https://github.com/DSheirer/jRTL/releases/download'
|
url = 'https://github.com/DSheirer/jRTL/releases/download'
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* *****************************************************************************
|
|
||||||
* Copyright (C) 2014-2025 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.buffer.airspy;
|
|
||||||
|
|
||||||
import io.github.dsheirer.buffer.AbstractNativeBuffer;
|
|
||||||
import io.github.dsheirer.sample.complex.ComplexSamples;
|
|
||||||
import io.github.dsheirer.sample.complex.InterleavedComplexSamples;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Native buffer implementation for Airspy HF+ & Discovery tuners.
|
|
||||||
*/
|
|
||||||
public class AirspyHfNativeBuffer extends AbstractNativeBuffer
|
|
||||||
{
|
|
||||||
public static final float SCALE = 1.0f / 32768.0f;
|
|
||||||
private short[] mInterleavedSamples;
|
|
||||||
private float mAverageDc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an instance.
|
|
||||||
* @param timestamp of the first sample of the buffer
|
|
||||||
* @param interleavedSamples pairs of 16-bit complex samples.
|
|
||||||
*/
|
|
||||||
public AirspyHfNativeBuffer(long timestamp, float samplesPerMillisecond, float averageDc, short[] interleavedSamples)
|
|
||||||
{
|
|
||||||
super(timestamp, samplesPerMillisecond);
|
|
||||||
mInterleavedSamples = interleavedSamples;
|
|
||||||
mAverageDc = averageDc;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<ComplexSamples> iterator()
|
|
||||||
{
|
|
||||||
return new IteratorComplexSamples();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterator<InterleavedComplexSamples> iteratorInterleaved()
|
|
||||||
{
|
|
||||||
return new IteratorInterleaved();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int sampleCount()
|
|
||||||
{
|
|
||||||
return mInterleavedSamples.length / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scalar implementation of complex samples buffer iterator
|
|
||||||
*/
|
|
||||||
public class IteratorComplexSamples implements Iterator<ComplexSamples>
|
|
||||||
{
|
|
||||||
private boolean mHasNext = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext()
|
|
||||||
{
|
|
||||||
return mHasNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ComplexSamples next()
|
|
||||||
{
|
|
||||||
int length = mInterleavedSamples.length / 2;
|
|
||||||
float[] i = new float[length];
|
|
||||||
float[] q = new float[length];
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
for(int x = 0; x < mInterleavedSamples.length; x += 2)
|
|
||||||
{
|
|
||||||
index = x / 2;
|
|
||||||
//Native ordering is in Q, I, Q, I ... reverse it to I, Q, I, Q
|
|
||||||
i[index] = (mInterleavedSamples[x + 1] * SCALE) - mAverageDc;
|
|
||||||
q[index] = (mInterleavedSamples[x] * SCALE) - mAverageDc;
|
|
||||||
}
|
|
||||||
|
|
||||||
mHasNext = false;
|
|
||||||
|
|
||||||
return new ComplexSamples(i, q, getTimestamp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scalar implementation of interleaved sample buffer iterator.
|
|
||||||
*/
|
|
||||||
public class IteratorInterleaved implements Iterator<InterleavedComplexSamples>
|
|
||||||
{
|
|
||||||
private boolean mHasNext = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasNext()
|
|
||||||
{
|
|
||||||
return mHasNext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InterleavedComplexSamples next()
|
|
||||||
{
|
|
||||||
float[] samples = new float[mInterleavedSamples.length];
|
|
||||||
|
|
||||||
for(int x = 0; x < mInterleavedSamples.length; x += 2)
|
|
||||||
{
|
|
||||||
//Native ordering is in Q, I, Q, I ... reverse it to I, Q, I, Q
|
|
||||||
samples[x] = (mInterleavedSamples[x + 1] * SCALE) - mAverageDc;
|
|
||||||
samples[x + 1] = (mInterleavedSamples[x] * SCALE) - mAverageDc;
|
|
||||||
}
|
|
||||||
|
|
||||||
mHasNext = false;
|
|
||||||
|
|
||||||
return new InterleavedComplexSamples(samples, getTimestamp());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
/*
|
|
||||||
* *****************************************************************************
|
|
||||||
* Copyright (C) 2014-2025 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.buffer.airspy;
|
|
||||||
|
|
||||||
import io.github.dsheirer.buffer.AbstractNativeBufferFactory;
|
|
||||||
import io.github.dsheirer.buffer.DcCorrectionManager;
|
|
||||||
import io.github.dsheirer.buffer.INativeBuffer;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Airspy HF+ native buffer factory.
|
|
||||||
*
|
|
||||||
* Note: the tuner provides 1024 samples in each transfer where samples are 16-bit interleaved complex.
|
|
||||||
*/
|
|
||||||
public class AirspyHfNativeBufferFactory extends AbstractNativeBufferFactory
|
|
||||||
{
|
|
||||||
private DcCorrectionManager mDcCorrectionManager = new DcCorrectionManager();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an instance
|
|
||||||
*/
|
|
||||||
public AirspyHfNativeBufferFactory()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the samples byte buffer into a native buffer and calculates DC offset
|
|
||||||
* @param samples byte array copied from native memory
|
|
||||||
* @param timestamp of the samples
|
|
||||||
* @return constructed native buffer
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public INativeBuffer getBuffer(ByteBuffer samples, long timestamp)
|
|
||||||
{
|
|
||||||
ShortBuffer shortBuffer = samples.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
|
|
||||||
short[] converted = new short[shortBuffer.capacity()];
|
|
||||||
shortBuffer.get(converted);
|
|
||||||
|
|
||||||
if(mDcCorrectionManager.shouldCalculateDc())
|
|
||||||
{
|
|
||||||
calculateDc(converted);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AirspyHfNativeBuffer(timestamp, getSamplesPerMillisecond(), mDcCorrectionManager.getAverageDc(), converted);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the average DC in the sample stream so that it can be subtracted from the samples when the
|
|
||||||
* native buffer is used.
|
|
||||||
* @param samples containing DC offset
|
|
||||||
*/
|
|
||||||
private void calculateDc(short[] samples)
|
|
||||||
{
|
|
||||||
float dcAccumulator = 0;
|
|
||||||
|
|
||||||
for(short sample: samples)
|
|
||||||
{
|
|
||||||
dcAccumulator += sample;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcAccumulator /= samples.length;
|
|
||||||
mDcCorrectionManager.adjust(dcAccumulator * AirspyHfNativeBuffer.SCALE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* *****************************************************************************
|
* *****************************************************************************
|
||||||
* Copyright (C) 2014-2024 Dennis Sheirer
|
* Copyright (C) 2014-2026 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
|
||||||
@@ -24,7 +24,6 @@ import io.github.dsheirer.source.SourceException;
|
|||||||
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
|
import io.github.dsheirer.source.tuner.manager.DiscoveredTuner;
|
||||||
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
import io.github.dsheirer.source.tuner.manager.TunerManager;
|
||||||
import io.github.dsheirer.source.tuner.ui.TunerEditor;
|
import io.github.dsheirer.source.tuner.ui.TunerEditor;
|
||||||
import java.io.IOException;
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -147,11 +146,9 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
if(hasTuner())
|
if(hasTuner())
|
||||||
{
|
{
|
||||||
getTunerIdLabel().setText("Airspy " + getTuner().getController().getBoardId() + " SER# " +
|
getTunerIdLabel().setText("Airspy " + getTuner().getController().getBoardId() + " SER# " +
|
||||||
getTuner().getController().getSerialNumber());
|
getTuner().getController().getSerialNumber() + " FW " + getTuner().getController().getFirmwareVersion());
|
||||||
|
|
||||||
//Permanently disable the sample rates combo and force 912kHz usage - during dev testing, attempts to use
|
getSampleRateCombo().setEnabled(!getTuner().getTunerController().isLockedSampleRate());
|
||||||
//the other sample rates produced inconsistent results.
|
|
||||||
getSampleRateCombo().setEnabled(false);
|
|
||||||
getSampleRateCombo().removeAllItems();
|
getSampleRateCombo().removeAllItems();
|
||||||
for(AirspyHfSampleRate sampleRate: getTuner().getController().getAvailableSampleRates())
|
for(AirspyHfSampleRate sampleRate: getTuner().getController().getAvailableSampleRates())
|
||||||
{
|
{
|
||||||
@@ -162,7 +159,7 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
getLnaToggleButton().setEnabled(true);
|
getLnaToggleButton().setEnabled(true);
|
||||||
getLnaToggleButton().setSelected(getTuner().getController().getLna());
|
getLnaToggleButton().setSelected(getTuner().getController().getLna());
|
||||||
getSampleRateCombo().setSelectedItem(getTuner().getController().getCurrentAirspySampleRate());
|
getSampleRateCombo().setSelectedItem(getTuner().getController().getCurrentAirspySampleRate());
|
||||||
getAttenuationCombo().setEnabled(true);
|
getAttenuationCombo().setEnabled(!getTuner().getController().getAgc());
|
||||||
getAttenuationCombo().setSelectedItem(getTuner().getController().getAttenuation());
|
getAttenuationCombo().setSelectedItem(getTuner().getController().getAttenuation());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -260,6 +257,7 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
if(mAttenuationCombo == null)
|
if(mAttenuationCombo == null)
|
||||||
{
|
{
|
||||||
mAttenuationCombo = new JComboBox<>(Attenuation.values());
|
mAttenuationCombo = new JComboBox<>(Attenuation.values());
|
||||||
|
mAttenuationCombo.setToolTipText("Attenuation applies when the AGC is off");
|
||||||
mAttenuationCombo.setEnabled(false);
|
mAttenuationCombo.setEnabled(false);
|
||||||
mAttenuationCombo.addActionListener(e -> {
|
mAttenuationCombo.addActionListener(e -> {
|
||||||
if(!isLoading())
|
if(!isLoading())
|
||||||
@@ -270,12 +268,12 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
getTuner().getController().setAttenuation(selected);
|
getTuner().getController().setAttenuation(selected);
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(SourceException se)
|
||||||
{
|
{
|
||||||
mLog.error("Error setting Airspy Hf attenuation [" + selected + "]", ioe);
|
mLog.error("Error setting Airspy Hf attenuation [" + selected + "]", se);
|
||||||
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
||||||
"Airspy Tuner Controller - couldn't apply attenuation setting [" +
|
"Airspy Tuner Controller - couldn't apply attenuation setting [" +
|
||||||
selected + "] " + ioe.getLocalizedMessage());
|
selected + "] " + se.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -300,13 +298,14 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
getTuner().getController().setAgc(mAgcToggleButton.isSelected());
|
getTuner().getController().setAgc(mAgcToggleButton.isSelected());
|
||||||
|
getAttenuationCombo().setEnabled(!mAgcToggleButton.isSelected());
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(SourceException se)
|
||||||
{
|
{
|
||||||
mLog.error("Error setting Airspy HF AGC", ioe);
|
mLog.error("Error setting Airspy HF AGC", se);
|
||||||
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
||||||
"Airspy HF Tuner Controller - couldn't change AGC setting" + ioe.getLocalizedMessage());
|
"Airspy HF Tuner Controller - couldn't change AGC setting" + se.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -333,11 +332,11 @@ public class AirspyHfTunerEditor extends TunerEditor<AirspyHfTuner,AirspyHfTuner
|
|||||||
getTuner().getController().setLna(mLnaToggleButton.isSelected());
|
getTuner().getController().setLna(mLnaToggleButton.isSelected());
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
catch(IOException ioe)
|
catch(SourceException se)
|
||||||
{
|
{
|
||||||
mLog.error("Error setting Airspy HF LNA", ioe);
|
mLog.error("Error setting Airspy HF LNA", se);
|
||||||
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
JOptionPane.showMessageDialog(AirspyHfTunerEditor.this,
|
||||||
"Airspy HF Tuner Controller - couldn't change LNA setting" + ioe.getLocalizedMessage());
|
"Airspy HF Tuner Controller - couldn't change LNA setting" + se.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* *****************************************************************************
|
|
||||||
* Copyright (C) 2014-2023 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.tuner.airspy.hf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Requests/Commands supported by the Airspy HF
|
|
||||||
*/
|
|
||||||
public enum Request
|
|
||||||
{
|
|
||||||
INVALID(0),
|
|
||||||
RECEIVER_MODE(1),
|
|
||||||
SET_FREQUENCY(2),
|
|
||||||
GET_SAMPLE_RATES(3),
|
|
||||||
SET_SAMPLE_RATE(4),
|
|
||||||
CONFIG_READ(5),
|
|
||||||
CONFIG_WRITE(6),
|
|
||||||
GET_SERIAL_NUMBER_BOARD_ID(7),
|
|
||||||
SET_USER_OUTPUT(8),
|
|
||||||
GET_VERSION_STRING(9),
|
|
||||||
SET_HF_AGC(10),
|
|
||||||
SET_HF_AGC_THRESHOLD(11),
|
|
||||||
SET_HF_ATT(12),
|
|
||||||
SET_HF_LNA(13),
|
|
||||||
GET_SAMPLE_RATE_ARCHITECTURES(14),
|
|
||||||
GET_FILTER_GAIN(15),
|
|
||||||
GET_FREQUENCY_DELTA(16),
|
|
||||||
SET_VCTCXO_CALIBRATION(17);
|
|
||||||
|
|
||||||
private int mValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs an instance
|
|
||||||
* @param value of the entry
|
|
||||||
*/
|
|
||||||
Request(int value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value associated with the entry
|
|
||||||
* @return value cast to a byte.
|
|
||||||
*/
|
|
||||||
public byte getRequest()
|
|
||||||
{
|
|
||||||
return (byte)mValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package io.github.dsheirer.source.tuner.airspy.hf;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Responses to Airspy HF requests
|
|
||||||
*/
|
|
||||||
public enum Response
|
|
||||||
{
|
|
||||||
SUCCESS(0),
|
|
||||||
ERROR(-1),
|
|
||||||
UNSUPPORTED(-2);
|
|
||||||
|
|
||||||
private int mValue;
|
|
||||||
|
|
||||||
Response(int value)
|
|
||||||
{
|
|
||||||
mValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup the enumeration entry from the value.
|
|
||||||
* @param value to lookup
|
|
||||||
* @return entry or UNSUPPORTED if there are no matches.
|
|
||||||
*/
|
|
||||||
public static Response fromValue(int value)
|
|
||||||
{
|
|
||||||
return switch(value)
|
|
||||||
{
|
|
||||||
case 0 -> SUCCESS;
|
|
||||||
case -1 -> ERROR;
|
|
||||||
default -> UNSUPPORTED;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
src/main/resources/52-airspyhf.rules
Executable file
1
src/main/resources/52-airspyhf.rules
Executable file
@@ -0,0 +1 @@
|
|||||||
|
ATTR{idVendor}=="03eb", ATTR{idProduct}=="800c", SYMLINK+="airspyhf-%k", MODE="660", GROUP="plugdev"
|
||||||
Reference in New Issue
Block a user