mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
156 lines
4.3 KiB
Java
156 lines
4.3 KiB
Java
/*******************************************************************************
|
|
* 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.airspy;
|
|
|
|
import dsp.filter.dc.DCRemovalFilter_RB;
|
|
import dsp.filter.hilbert.HilbertTransform;
|
|
import sample.adapter.ISampleAdapter;
|
|
|
|
public class AirspySampleAdapter implements ISampleAdapter
|
|
{
|
|
private static final float SCALE_SIGNED_12_BIT_TO_FLOAT = 1.0f / 2048.0f;
|
|
|
|
private DCRemovalFilter_RB mDCFilter = new DCRemovalFilter_RB(0.01f);
|
|
private HilbertTransform mHilbertTransform = new HilbertTransform();
|
|
private boolean mSamplePacking = false;
|
|
|
|
|
|
/**
|
|
* Adapter to translate byte buffers received from the airspy tuner into
|
|
* float buffers for processing.
|
|
*/
|
|
public AirspySampleAdapter()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Sample packing places two 12-bit samples into 3 bytes when enabled or
|
|
* places two 12-bit samples into 4 bytes when disabled.
|
|
*
|
|
* @param enabled
|
|
*/
|
|
public void setSamplePacking(boolean enabled)
|
|
{
|
|
mSamplePacking = enabled;
|
|
}
|
|
|
|
@Override
|
|
public float[] convert(byte[] samples)
|
|
{
|
|
float[] realSamples;
|
|
|
|
if(mSamplePacking)
|
|
{
|
|
realSamples = convertPacked(samples);
|
|
}
|
|
else
|
|
{
|
|
realSamples = convertUnpacked(samples);
|
|
}
|
|
|
|
mDCFilter.filter(realSamples);
|
|
|
|
return mHilbertTransform.filter(realSamples);
|
|
}
|
|
|
|
/**
|
|
* Converts the byte array containing unsigned 12-bit short values into
|
|
* signed float values in the range -1 to 1;
|
|
*
|
|
* @param data - byte array of unsigned 16-bit values
|
|
* @return converted float values
|
|
*/
|
|
private float[] convertUnpacked(byte[] data)
|
|
{
|
|
float[] samples = new float[data.length / 2];
|
|
|
|
int pointer = 0;
|
|
|
|
for(int x = 0; x < data.length; x += 2)
|
|
{
|
|
samples[pointer++] = scale((data[x] & 0xFF) |
|
|
(data[x + 1] << 8));
|
|
}
|
|
|
|
return samples;
|
|
}
|
|
|
|
/**
|
|
* Converts every 3 bytes containing a pair of 12-bit unsigned values into
|
|
* a pair of float values in the range -1 to 1;
|
|
*
|
|
* @param data1 - byte array of unsigned 12-bit values
|
|
* @return converted float values
|
|
*/
|
|
private float[] convertPacked(byte[] data1)
|
|
{
|
|
byte[] data = new byte[data1.length];
|
|
|
|
//Convert big-endian to little-endian
|
|
for(int x = 0; x < data1.length; x += 4)
|
|
{
|
|
data[x] = data1[x + 3];
|
|
data[x + 1] = data1[x + 2];
|
|
data[x + 2] = data1[x + 1];
|
|
data[x + 3] = data1[x];
|
|
}
|
|
|
|
int count = (int) ((float) data.length / 1.5f);
|
|
|
|
/* Ensure we have an even number of samples */
|
|
if(count % 2 == 1)
|
|
{
|
|
count--;
|
|
}
|
|
|
|
int bytes = (int) ((float) count * 1.5f);
|
|
|
|
float[] samples = new float[count];
|
|
|
|
int pointer = 0;
|
|
|
|
int first;
|
|
int second;
|
|
|
|
for(int x = 0; x < bytes; x += 3)
|
|
{
|
|
first = ((data[x] << 4) & 0xFF0) |
|
|
((data[x + 1] >> 4) & 0xF);
|
|
|
|
samples[pointer++] = scale(first);
|
|
|
|
second = ((data[x + 1] << 8) & 0xF00) |
|
|
(data[x + 2] & 0xFF);
|
|
|
|
samples[pointer++] = scale(second);
|
|
}
|
|
|
|
return samples;
|
|
}
|
|
|
|
/**
|
|
* Converts unsigned 12-bit values to signed 12-bit values and then scales
|
|
* the signed value to a signed float value in range: -1.0 : +1.0
|
|
*/
|
|
public static float scale(int value)
|
|
{
|
|
return (float) ((value & 0xFFF) - 2048) * SCALE_SIGNED_12_BIT_TO_FLOAT;
|
|
}
|
|
}
|