mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
330 - Adds new JavaFX implementation of the demodulator viewer applicaiton
with initial support for playback control and I/Q sample axis viewing.
This commit is contained in:
@@ -54,6 +54,8 @@ dependencies {
|
||||
compile 'org.apache.axis:axis-jaxrpc:1.4'
|
||||
compile 'org.apache.axis:axis:1.4'
|
||||
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.3'
|
||||
compile 'org.kordamp.ikonli:ikonli-javafx:2.1.1'
|
||||
compile 'org.kordamp.ikonli:ikonli-fontawesome-pack:2.1.1'
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
*
|
||||
* Copyright (C) 2014-2018 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/>
|
||||
******************************************************************************/
|
||||
@@ -25,66 +25,83 @@ import java.util.Arrays;
|
||||
* Circular sample buffer - allocates a buffer and stores samples in a circular
|
||||
* fashion, overwriting older samples with newly arrived samples. Initially
|
||||
* fills buffer with 0-valued samples
|
||||
*
|
||||
*
|
||||
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
|
||||
*/
|
||||
public class ComplexCircularBuffer
|
||||
{
|
||||
Complex[] mBuffer;
|
||||
int mBufferPointer = 0;
|
||||
|
||||
public ComplexCircularBuffer( int size )
|
||||
{
|
||||
mBuffer = new Complex[ size ];
|
||||
|
||||
Arrays.fill( mBuffer, new Complex( 1.0f, 1.0f ) );
|
||||
}
|
||||
Complex[] mBuffer;
|
||||
int mBufferPointer = 0;
|
||||
|
||||
/**
|
||||
* Returns the sample currently pointed to in the buffer and stores the
|
||||
* new sample in its place
|
||||
* @param sample
|
||||
* @return
|
||||
*/
|
||||
public Complex get( Complex sample )
|
||||
{
|
||||
Complex retVal = mBuffer[ mBufferPointer ];
|
||||
public ComplexCircularBuffer(int size)
|
||||
{
|
||||
mBuffer = new Complex[size];
|
||||
|
||||
put( sample );
|
||||
Arrays.fill(mBuffer, new Complex(1.0f, 1.0f));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void put( Complex sample )
|
||||
{
|
||||
mBuffer[ mBufferPointer ] = sample;
|
||||
public int length()
|
||||
{
|
||||
return mBuffer.length;
|
||||
}
|
||||
|
||||
mBufferPointer++;
|
||||
|
||||
if( mBufferPointer >= mBuffer.length )
|
||||
{
|
||||
mBufferPointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Complex[] get( int count )
|
||||
{
|
||||
Complex[] samples = new Complex[ count ];
|
||||
|
||||
int tempCounter = mBufferPointer;
|
||||
/**
|
||||
* Returns the sample currently pointed to in the buffer and stores the
|
||||
* new sample in its place
|
||||
*
|
||||
* @param sample
|
||||
* @return
|
||||
*/
|
||||
public Complex get(Complex sample)
|
||||
{
|
||||
Complex retVal = mBuffer[mBufferPointer];
|
||||
|
||||
for( int x = 0; x < count; x++ )
|
||||
{
|
||||
samples[ x ] = mBuffer[ tempCounter ];
|
||||
|
||||
tempCounter++;
|
||||
|
||||
if( tempCounter > mBuffer.length - 1 )
|
||||
{
|
||||
tempCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
put(sample);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void put(Complex sample)
|
||||
{
|
||||
mBuffer[mBufferPointer] = sample;
|
||||
|
||||
mBufferPointer++;
|
||||
|
||||
if(mBufferPointer >= mBuffer.length)
|
||||
{
|
||||
mBufferPointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the (count) oldest samples in a time ordered array
|
||||
*/
|
||||
public Complex[] get(int count)
|
||||
{
|
||||
Complex[] samples = new Complex[count];
|
||||
|
||||
int tempCounter = mBufferPointer;
|
||||
|
||||
for(int x = 0; x < count; x++)
|
||||
{
|
||||
samples[x] = mBuffer[tempCounter];
|
||||
|
||||
tempCounter++;
|
||||
|
||||
if(tempCounter > mBuffer.length - 1)
|
||||
{
|
||||
tempCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples in a time-ordered array
|
||||
*/
|
||||
public Complex[] getAll()
|
||||
{
|
||||
return get(length());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,27 +5,34 @@ import io.github.dsheirer.sample.complex.Complex;
|
||||
|
||||
public class ComplexGain implements Listener<Complex>
|
||||
{
|
||||
private float mGain;
|
||||
private Listener<Complex> mListener;
|
||||
private float mGain;
|
||||
private Listener<Complex> mListener;
|
||||
|
||||
public ComplexGain( float gain )
|
||||
{
|
||||
mGain = gain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Complex sample )
|
||||
{
|
||||
if( mListener != null )
|
||||
{
|
||||
sample.multiply( mGain );
|
||||
|
||||
mListener.receive( sample );
|
||||
}
|
||||
}
|
||||
public ComplexGain(float gain)
|
||||
{
|
||||
mGain = gain;
|
||||
}
|
||||
|
||||
public void setListener( Listener<Complex> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
public Complex apply(Complex sample)
|
||||
{
|
||||
sample.multiply(mGain);
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(Complex sample)
|
||||
{
|
||||
if(mListener != null)
|
||||
{
|
||||
apply(sample);
|
||||
|
||||
mListener.receive(sample);
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener(Listener<Complex> listener)
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*******************************************************************************
|
||||
* sdr-trunk
|
||||
* Copyright (C) 2014-2018 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.instrument.gui.viewer;
|
||||
|
||||
import io.github.dsheirer.buffer.ComplexCircularBuffer;
|
||||
import io.github.dsheirer.dsp.gain.ComplexGain;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.Complex;
|
||||
import io.github.dsheirer.sample.complex.ComplexBuffer;
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ComplexSampleLineChart extends LineChart implements Listener<ComplexBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(ComplexSampleLineChart.class);
|
||||
|
||||
private ComplexCircularBuffer mComplexCircularBuffer;
|
||||
private ComplexGain mComplexGain = new ComplexGain(1000.0f);
|
||||
private ObservableList<XYChart.Data<Integer,Float>> mISamples = FXCollections.observableArrayList();
|
||||
private ObservableList<XYChart.Data<Integer,Float>> mQSamples = FXCollections.observableArrayList();
|
||||
private IntegerProperty mLengthProperty = new SimpleIntegerProperty(40);
|
||||
|
||||
public ComplexSampleLineChart(int length)
|
||||
{
|
||||
super(new NumberAxis("Sample Number", 1, length, 1),
|
||||
new NumberAxis("Value", -1.0, 1.0, 0.1));
|
||||
|
||||
LineChart.Series<Integer,Float> iSampleSeries = new LineChart.Series<>("Inphase", mISamples);
|
||||
LineChart.Series<Integer,Float> qSampleSeries = new LineChart.Series<>("Quadrature", mQSamples);
|
||||
ObservableList<XYChart.Series<Integer,Float>> observableList =
|
||||
FXCollections.observableArrayList(iSampleSeries, qSampleSeries);
|
||||
|
||||
setData(observableList);
|
||||
init(length);
|
||||
}
|
||||
|
||||
private void init(int length)
|
||||
{
|
||||
mLengthProperty.addListener(new ChangeListener<Number>()
|
||||
{
|
||||
@Override
|
||||
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue)
|
||||
{
|
||||
mComplexCircularBuffer = new ComplexCircularBuffer(newValue.intValue());
|
||||
}
|
||||
});
|
||||
mComplexCircularBuffer = new ComplexCircularBuffer(length);
|
||||
length().setValue(length);
|
||||
|
||||
for(int x = 1; x <= length; x++)
|
||||
{
|
||||
mISamples.add(new Data(x, 0.0f));
|
||||
mQSamples.add(new Data(x, 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the x-axis for displaying samples
|
||||
*/
|
||||
public IntegerProperty length()
|
||||
{
|
||||
return mLengthProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ComplexBuffer complexBuffer)
|
||||
{
|
||||
float[] samples = complexBuffer.getSamples();
|
||||
|
||||
Complex sample;
|
||||
|
||||
for(int x = 0; x < samples.length; x += 2)
|
||||
{
|
||||
sample = new Complex(samples[x], samples[x + 1]);
|
||||
mComplexGain.apply(sample);
|
||||
mComplexCircularBuffer.put(sample);
|
||||
}
|
||||
|
||||
updateChart();
|
||||
}
|
||||
|
||||
private void updateChart()
|
||||
{
|
||||
Complex[] samples = mComplexCircularBuffer.getAll();
|
||||
|
||||
for(int x = 0; x < samples.length; x++)
|
||||
{
|
||||
Complex sample = samples[x];
|
||||
|
||||
if(sample != null)
|
||||
{
|
||||
mISamples.get(x).setYValue(sample.inphase());
|
||||
mQSamples.get(x).setYValue(sample.quadrature());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,67 +15,263 @@
|
||||
******************************************************************************/
|
||||
package io.github.dsheirer.instrument.gui.viewer;
|
||||
|
||||
import io.github.dsheirer.sample.Broadcaster;
|
||||
import io.github.dsheirer.sample.Listener;
|
||||
import io.github.dsheirer.sample.complex.ComplexBuffer;
|
||||
import io.github.dsheirer.source.IControllableFileSource;
|
||||
import io.github.dsheirer.source.IFrameLocationListener;
|
||||
import io.github.dsheirer.source.wave.ComplexWaveSource;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.HBox;
|
||||
import org.kordamp.ikonli.fontawesome.FontAwesome;
|
||||
import org.kordamp.ikonli.javafx.FontIcon;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class PlaybackController extends HBox
|
||||
public class PlaybackController extends HBox implements IFrameLocationListener, Listener<ComplexBuffer>
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(PlaybackController.class);
|
||||
|
||||
private Button mRewindButton;
|
||||
private TextField mPlaybackPositionText;
|
||||
private Button mPlay1Button;
|
||||
private Button mPlay10Button;
|
||||
private Button mPlay100Button;
|
||||
private Button mPlay1000Button;
|
||||
private HBox mControlsBox;
|
||||
private Label mFileLabel;
|
||||
private EventHandler<ActionEvent> mPlayEventHandler;
|
||||
|
||||
private IControllableFileSource mControllableFileSource;
|
||||
private Broadcaster<ComplexBuffer> mComplexBufferBroadcaster = new Broadcaster<>();
|
||||
|
||||
public PlaybackController()
|
||||
{
|
||||
getChildren().addAll(getPlay1Button(), getPlay10Button(), getPlay100Button(), getPlay1000Button());
|
||||
super(10);
|
||||
|
||||
getChildren().addAll(getControlsBox(), getFileLabel());
|
||||
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
|
||||
public void load(Path path)
|
||||
public void load(File file)
|
||||
{
|
||||
if(file != null && file.isFile())
|
||||
{
|
||||
try
|
||||
{
|
||||
mControllableFileSource = new ComplexWaveSource(file);
|
||||
mControllableFileSource.setListener(this);
|
||||
((ComplexWaveSource)mControllableFileSource).setListener((Listener<ComplexBuffer>)this);
|
||||
mControllableFileSource.open();
|
||||
}
|
||||
catch(UnsupportedAudioFileException e)
|
||||
{
|
||||
mLog.error("Unsupported Audio File Type [" + (file != null ? file.getAbsolutePath() : "null") + "]");
|
||||
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, "The file type is unsupported.", ButtonType.OK);
|
||||
alert.show();
|
||||
return;
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
mLog.error("Error opening file [" + (file != null ? file.getAbsolutePath() : "null") + "]");
|
||||
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR, "There was an error opening the file",
|
||||
ButtonType.OK);
|
||||
alert.show();
|
||||
return;
|
||||
}
|
||||
|
||||
getFileLabel().setText(file.getName());
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public Button getPlay1Button()
|
||||
/**
|
||||
* Adds listener to receive complex buffers from this playback
|
||||
*/
|
||||
public void addListener(Listener<ComplexBuffer> listener)
|
||||
{
|
||||
mComplexBufferBroadcaster.addListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving complex buffers from this playback
|
||||
*/
|
||||
public void removeListener(Listener<ComplexBuffer> listener)
|
||||
{
|
||||
mComplexBufferBroadcaster.removeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all of the playback controls to the specified enabled state.
|
||||
*/
|
||||
private void setControlsEnabled(boolean enabled)
|
||||
{
|
||||
getRewindButton().setDisable(!enabled);
|
||||
getPlaybackPositionText().setDisable(!enabled);
|
||||
getPlay1Button().setDisable(!enabled);
|
||||
getPlay10Button().setDisable(!enabled);
|
||||
getPlay100Button().setDisable(!enabled);
|
||||
getPlay1000Button().setDisable(!enabled);
|
||||
}
|
||||
|
||||
private HBox getControlsBox()
|
||||
{
|
||||
if(mControlsBox == null)
|
||||
{
|
||||
mControlsBox = new HBox();
|
||||
|
||||
mControlsBox.getChildren().addAll(getRewindButton(), getPlaybackPositionText(), getPlay1Button(),
|
||||
getPlay10Button(), getPlay100Button(), getPlay1000Button());
|
||||
}
|
||||
|
||||
return mControlsBox;
|
||||
}
|
||||
|
||||
|
||||
private Button getRewindButton()
|
||||
{
|
||||
if(mRewindButton == null)
|
||||
{
|
||||
mRewindButton = new Button();
|
||||
mRewindButton.setGraphic(new FontIcon(FontAwesome.FAST_BACKWARD));
|
||||
}
|
||||
|
||||
return mRewindButton;
|
||||
}
|
||||
|
||||
private Button getPlay1Button()
|
||||
{
|
||||
if(mPlay1Button == null)
|
||||
{
|
||||
mPlay1Button = new Button("> 1");
|
||||
mPlay1Button = new Button("1");
|
||||
mPlay1Button.setUserData(1);
|
||||
mPlay1Button.setOnAction(getPlaybackEventHandler());
|
||||
mPlay1Button.setGraphic(new FontIcon(FontAwesome.PLAY));
|
||||
}
|
||||
|
||||
return mPlay1Button;
|
||||
}
|
||||
|
||||
public Button getPlay10Button()
|
||||
private Button getPlay10Button()
|
||||
{
|
||||
if(mPlay10Button == null)
|
||||
{
|
||||
mPlay10Button = new Button(">> 10");
|
||||
mPlay10Button = new Button("10");
|
||||
mPlay10Button.setUserData(10);
|
||||
mPlay10Button.setOnAction(getPlaybackEventHandler());
|
||||
mPlay10Button.setGraphic(new FontIcon(FontAwesome.FAST_FORWARD));
|
||||
}
|
||||
|
||||
return mPlay10Button;
|
||||
}
|
||||
|
||||
public Button getPlay100Button()
|
||||
private Button getPlay100Button()
|
||||
{
|
||||
if(mPlay100Button == null)
|
||||
{
|
||||
mPlay100Button = new Button(">> 100");
|
||||
mPlay100Button = new Button("100");
|
||||
mPlay100Button.setUserData(100);
|
||||
mPlay100Button.setOnAction(getPlaybackEventHandler());
|
||||
mPlay100Button.setGraphic(new FontIcon(FontAwesome.FAST_FORWARD));
|
||||
}
|
||||
|
||||
return mPlay100Button;
|
||||
}
|
||||
|
||||
public Button getPlay1000Button()
|
||||
private Button getPlay1000Button()
|
||||
{
|
||||
if(mPlay1000Button == null)
|
||||
{
|
||||
mPlay1000Button = new Button(">> 1000");
|
||||
mPlay1000Button = new Button("1000");
|
||||
mPlay1000Button.setUserData(1000);
|
||||
mPlay1000Button.setOnAction(getPlaybackEventHandler());
|
||||
mPlay1000Button.setGraphic(new FontIcon(FontAwesome.FAST_FORWARD));
|
||||
}
|
||||
|
||||
return mPlay1000Button;
|
||||
}
|
||||
|
||||
private EventHandler<ActionEvent> getPlaybackEventHandler()
|
||||
{
|
||||
if(mPlayEventHandler == null)
|
||||
{
|
||||
mPlayEventHandler = new EventHandler<ActionEvent>()
|
||||
{
|
||||
@Override
|
||||
public void handle(ActionEvent event)
|
||||
{
|
||||
int count = (int)((Button)event.getSource()).getUserData();
|
||||
|
||||
if(mControllableFileSource != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
mControllableFileSource.next(count, true);
|
||||
}
|
||||
catch(IOException ioe)
|
||||
{
|
||||
mLog.error("Error while playing samples");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return mPlayEventHandler;
|
||||
}
|
||||
|
||||
private TextField getPlaybackPositionText()
|
||||
{
|
||||
if(mPlaybackPositionText == null)
|
||||
{
|
||||
mPlaybackPositionText = new TextField("0");
|
||||
mPlaybackPositionText.setAlignment(Pos.CENTER);
|
||||
mPlaybackPositionText.setPrefWidth(80);
|
||||
}
|
||||
|
||||
return mPlaybackPositionText;
|
||||
}
|
||||
|
||||
private Label getFileLabel()
|
||||
{
|
||||
if(mFileLabel == null)
|
||||
{
|
||||
mFileLabel = new Label();
|
||||
}
|
||||
|
||||
return mFileLabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frameLocationUpdated(int location)
|
||||
{
|
||||
getPlaybackPositionText().setText(String.valueOf(location));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void frameLocationReset()
|
||||
{
|
||||
mLog.info("Frame location reset ... ignoring?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive(ComplexBuffer complexBuffer)
|
||||
{
|
||||
mComplexBufferBroadcaster.broadcast(complexBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,15 +22,18 @@ import java.io.File;
|
||||
public class ViewerDesktop extends BorderPane
|
||||
{
|
||||
private PlaybackController mPlaybackController;
|
||||
private ComplexSampleLineChart mSampleLineChart;
|
||||
|
||||
public ViewerDesktop()
|
||||
{
|
||||
setBottom(getPlaybackController());
|
||||
getPlaybackController().addListener(getSampleLineChart());
|
||||
setCenter(getSampleLineChart());
|
||||
}
|
||||
|
||||
public void load(File file)
|
||||
{
|
||||
|
||||
getPlaybackController().load(file);
|
||||
}
|
||||
|
||||
public void close()
|
||||
@@ -47,4 +50,15 @@ public class ViewerDesktop extends BorderPane
|
||||
|
||||
return mPlaybackController;
|
||||
}
|
||||
|
||||
|
||||
private ComplexSampleLineChart getSampleLineChart()
|
||||
{
|
||||
if(mSampleLineChart == null)
|
||||
{
|
||||
mSampleLineChart = new ComplexSampleLineChart(40);
|
||||
}
|
||||
|
||||
return mSampleLineChart;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@ public class ConversionUtils
|
||||
*/
|
||||
public static float[] convertFromSigned16BitSamples( ByteBuffer buffer )
|
||||
{
|
||||
ShortBuffer byteBuffer =
|
||||
buffer.order( ByteOrder.LITTLE_ENDIAN ).asShortBuffer();
|
||||
ShortBuffer byteBuffer = buffer.order( ByteOrder.LITTLE_ENDIAN ).asShortBuffer();
|
||||
|
||||
float[] samples = new float[ buffer.limit() / 2 ];
|
||||
|
||||
for( int x = 0; x < samples.length; x++ )
|
||||
{
|
||||
samples[ x ] = (float)byteBuffer.get() / 32767.0f;
|
||||
samples[ x ] = (float)byteBuffer.get() / (float)Short.MAX_VALUE;
|
||||
}
|
||||
|
||||
return samples;
|
||||
|
||||
@@ -239,8 +239,7 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
|
||||
buffer = Arrays.copyOf(buffer, samplesRead);
|
||||
}
|
||||
|
||||
float[] samples = ConversionUtils
|
||||
.convertFromSigned16BitSamples(buffer);
|
||||
float[] samples = ConversionUtils.convertFromSigned16BitSamples(buffer);
|
||||
|
||||
mListener.receive(new ComplexBuffer(samples));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user