mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-13 00:57:31 -05:00
Initial code check in continued
This commit is contained in:
97
src/audio/AudioAdapter.java
Normal file
97
src/audio/AudioAdapter.java
Normal file
@@ -0,0 +1,97 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
import util.Oscillator;
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.FloatFIRFilter;
|
||||
import dsp.filter.Window.WindowType;
|
||||
|
||||
/**
|
||||
* Based on the AudioType applied, produces normal, muted, or audio inverted
|
||||
* audio output.
|
||||
*/
|
||||
public class AudioAdapter
|
||||
{
|
||||
private static int mGain = 5;
|
||||
private Oscillator mSineWaveGenerator;
|
||||
private FloatFIRFilter mPostInversionFilter;
|
||||
private FloatFIRFilter mAudioHighPassFilter;
|
||||
private AudioType mAudioType = AudioType.NORMAL;
|
||||
private int mSampleRate;
|
||||
|
||||
public AudioAdapter( int sampleRate )
|
||||
{
|
||||
mSampleRate = sampleRate;
|
||||
mSineWaveGenerator = new Oscillator( 3000, mSampleRate );
|
||||
mAudioHighPassFilter = new FloatFIRFilter(
|
||||
FilterFactory.getHighPass( mSampleRate, 200, 1600, 48,
|
||||
WindowType.HAMMING, true ), mGain );
|
||||
mPostInversionFilter = new FloatFIRFilter(
|
||||
FilterFactory.getLowPass( mSampleRate, 3000, 5000, 48,
|
||||
WindowType.HAMMING, true ), mGain );
|
||||
}
|
||||
|
||||
public void setAudioType( AudioType type )
|
||||
{
|
||||
if( type != null && type != mAudioType )
|
||||
{
|
||||
mAudioType = type;
|
||||
|
||||
int inversionFrequency = type.getAudioInversionFrequency();
|
||||
|
||||
if( inversionFrequency != 0 )
|
||||
{
|
||||
mSineWaveGenerator.setFrequency( inversionFrequency );;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float get( float sample )
|
||||
{
|
||||
float retVal;
|
||||
|
||||
switch( mAudioType )
|
||||
{
|
||||
case NORMAL:
|
||||
retVal = mAudioHighPassFilter.get( sample );
|
||||
break;
|
||||
case MUTE:
|
||||
retVal = 0.0f;
|
||||
break;
|
||||
case INV2632:
|
||||
case INV2718:
|
||||
case INV2868:
|
||||
case INV3023:
|
||||
case INV3107:
|
||||
case INV3196:
|
||||
case INV3333:
|
||||
case INV3339:
|
||||
case INV3496:
|
||||
case INV3729:
|
||||
case INV4096:
|
||||
default:
|
||||
retVal = (float)( mPostInversionFilter.get(
|
||||
mAudioHighPassFilter.get( sample ) *
|
||||
mSineWaveGenerator.nextFloat() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
82
src/audio/AudioInverter.java
Normal file
82
src/audio/AudioInverter.java
Normal file
@@ -0,0 +1,82 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
import sample.Listener;
|
||||
import util.Oscillator;
|
||||
import dsp.filter.Filters;
|
||||
import dsp.filter.FloatFIRFilter;
|
||||
|
||||
/**
|
||||
* Applies audio inversion (or un-inversion) to a stream of float audio samples
|
||||
* by multiplying each successive sample by either a 1 or a -1 value.
|
||||
*/
|
||||
public class AudioInverter implements Listener<Float>
|
||||
{
|
||||
private Oscillator mSineWaveGenerator;
|
||||
private FloatFIRFilter mPostInversionLowPassFilter;
|
||||
private Listener<Float> mListener;
|
||||
|
||||
public AudioInverter( int inversionFrequency, int sampleRate )
|
||||
{
|
||||
mSineWaveGenerator = new Oscillator( inversionFrequency, sampleRate );
|
||||
|
||||
mPostInversionLowPassFilter = new FloatFIRFilter(
|
||||
Filters.FIRLP_55TAP_48000FS_3000FC.getCoefficients(), 1.04 );
|
||||
|
||||
mPostInversionLowPassFilter.setListener( new FilteredSampleProcessor() );
|
||||
}
|
||||
|
||||
public AudioInverter( InversionFrequency frequency, int sampleRate )
|
||||
{
|
||||
this( frequency.getFrequency(), sampleRate );
|
||||
}
|
||||
|
||||
public void setListener( Listener<Float> listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Float sample )
|
||||
{
|
||||
//Multiply the sample by the folding frequency and then send it to
|
||||
//the low pass filter
|
||||
if( mPostInversionLowPassFilter != null )
|
||||
{
|
||||
mPostInversionLowPassFilter.receive(
|
||||
sample * mSineWaveGenerator.nextFloat() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple class to receive the output of the FIR low pass filter and then
|
||||
* send it to the registered listener(s)
|
||||
*/
|
||||
class FilteredSampleProcessor implements Listener<Float>
|
||||
{
|
||||
@Override
|
||||
public void receive( Float sample )
|
||||
{
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( sample );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
src/audio/AudioOutput.java
Normal file
116
src/audio/AudioOutput.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.LineUnavailableException;
|
||||
import javax.sound.sampled.SourceDataLine;
|
||||
|
||||
import log.Log;
|
||||
import sample.Listener;
|
||||
import buffer.FloatSampleBufferAssembler;
|
||||
|
||||
public class AudioOutput implements Listener<Float>,
|
||||
SquelchListener,
|
||||
AudioTypeListener
|
||||
{
|
||||
private static final int sAUDIO_BLOCK_SIZE = 24000;
|
||||
|
||||
private static final AudioFormat sAUDIO_FORMAT =
|
||||
new AudioFormat( 48000, //SampleRate
|
||||
16, //Sample Size
|
||||
1, //Channels
|
||||
true, //Signed
|
||||
false ); //Little Endian
|
||||
|
||||
private AudioAdapter mAdapter = new AudioAdapter( 48000 );
|
||||
|
||||
private FloatSampleBufferAssembler mBuffer =
|
||||
new FloatSampleBufferAssembler( sAUDIO_BLOCK_SIZE );
|
||||
private SourceDataLine mOutput;
|
||||
|
||||
private boolean mEnabled = false;
|
||||
private SquelchState mSquelchState = SquelchState.SQUELCH;
|
||||
|
||||
public AudioOutput( String channelName )
|
||||
{
|
||||
try
|
||||
{
|
||||
mOutput = AudioSystem.getSourceDataLine( sAUDIO_FORMAT );
|
||||
mOutput.open( sAUDIO_FORMAT, (int)( sAUDIO_FORMAT.getSampleRate() ) );
|
||||
mOutput.start();
|
||||
}
|
||||
catch ( LineUnavailableException e )
|
||||
{
|
||||
Log.warning( "AudioOutput - couldn't open audio speakers "
|
||||
+ "for playback:" + e.getLocalizedMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSquelch( SquelchState state )
|
||||
{
|
||||
mSquelchState = state;
|
||||
}
|
||||
|
||||
public void setAudioPlaybackEnabled( boolean enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mOutput.stop();
|
||||
mOutput.close();
|
||||
mOutput = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( Float sample )
|
||||
{
|
||||
float outputSample = mAdapter.get( sample );
|
||||
|
||||
if( mEnabled && mSquelchState == SquelchState.UNSQUELCH )
|
||||
{
|
||||
mBuffer.put( outputSample );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use 0-valued samples when we're disabled or squelched */
|
||||
mBuffer.put( 0.0f );
|
||||
}
|
||||
|
||||
if( !mBuffer.hasRemaining() )
|
||||
{
|
||||
ByteBuffer buffer = mBuffer.get();
|
||||
|
||||
mOutput.write( buffer.array(), 0, buffer.array().length );
|
||||
|
||||
mBuffer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioType( AudioType type )
|
||||
{
|
||||
mAdapter.setAudioType( type );
|
||||
}
|
||||
}
|
||||
87
src/audio/AudioType.java
Normal file
87
src/audio/AudioType.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
public enum AudioType
|
||||
{
|
||||
NORMAL( "Normal Audio", "Clear", 0 ),
|
||||
MUTE( "Muted Audio", "Muted", 0 ),
|
||||
INV2500( "Inverted Audio 2500Hz", "Inverted", 2500 ),
|
||||
INV2550( "Inverted Audio 2550Hz", "Inverted", 2550 ),
|
||||
INV2600( "Inverted Audio 2600Hz", "Inverted", 2600 ),
|
||||
INV2632( "Inverted Audio 2632Hz", "Inverted", 2632 ),
|
||||
INV2675( "Inverted Audio 2675Hz", "Inverted", 2675 ),
|
||||
INV2718( "Inverted Audio 2718Hz", "Inverted", 2718 ),
|
||||
INV2725( "Inverted Audio 2725Hz", "Inverted", 2725 ),
|
||||
INV2750( "Inverted Audio 2750Hz", "Inverted", 2750 ),
|
||||
INV2760( "Inverted Audio 2760Hz", "Inverted", 2760 ),
|
||||
INV2775( "Inverted Audio 2775Hz", "Inverted", 2775 ),
|
||||
INV2800( "Inverted Audio 2800Hz", "Inverted", 2800 ),
|
||||
INV2825( "Inverted Audio 2825Hz", "Inverted", 2825 ),
|
||||
INV2868( "Inverted Audio 2868Hz", "Inverted", 2868 ),
|
||||
INV3023( "Inverted Audio 3023Hz", "Inverted", 3023 ),
|
||||
INV3107( "Inverted Audio 3107Hz", "Inverted", 3107 ),
|
||||
INV3196( "Inverted Audio 3196Hz", "Inverted", 3196 ),
|
||||
INV3333( "Inverted Audio 3333Hz", "Inverted", 3333 ),
|
||||
INV3339( "Inverted Audio 3339Hz", "Inverted", 3339 ),
|
||||
INV3360( "Inverted Audio 3360Hz", "Inverted", 3360 ),
|
||||
INV3375( "Inverted Audio 3375Hz", "Inverted", 3375 ),
|
||||
INV3400( "Inverted Audio 3400Hz", "Inverted", 3400 ),
|
||||
INV3450( "Inverted Audio 3450Hz", "Inverted", 3450 ),
|
||||
INV3496( "Inverted Audio 3496Hz", "Inverted", 3496 ),
|
||||
INV3729( "Inverted Audio 3729Hz", "Inverted", 3729 ),
|
||||
INV4096( "Inverted Audio 4096Hz", "Inverted", 4096 ),
|
||||
INV4300( "Inverted Audio 4300Hz", "Inverted", 4300 ),
|
||||
INV4500( "Inverted Audio 4500Hz", "Inverted", 4500 ),
|
||||
INV4700( "Inverted Audio 4700Hz", "Inverted", 4700 ),
|
||||
INV4900( "Inverted Audio 4900Hz", "Inverted", 4900 );
|
||||
|
||||
private String mDisplayString;
|
||||
private String mShortDisplayString;
|
||||
private int mAudioInversionFrequency;
|
||||
|
||||
AudioType( String displayString,
|
||||
String shortDisplayString,
|
||||
int inversionFrequency )
|
||||
{
|
||||
mDisplayString = displayString;
|
||||
mShortDisplayString = shortDisplayString;
|
||||
mAudioInversionFrequency = inversionFrequency;
|
||||
}
|
||||
|
||||
public String getDisplayString()
|
||||
{
|
||||
return mDisplayString;
|
||||
}
|
||||
|
||||
public String getShortDisplayString()
|
||||
{
|
||||
return mShortDisplayString;
|
||||
}
|
||||
|
||||
public int getAudioInversionFrequency()
|
||||
{
|
||||
return mAudioInversionFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return mDisplayString;
|
||||
}
|
||||
}
|
||||
23
src/audio/AudioTypeListener.java
Normal file
23
src/audio/AudioTypeListener.java
Normal file
@@ -0,0 +1,23 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
public interface AudioTypeListener
|
||||
{
|
||||
public void setAudioType( AudioType type );
|
||||
}
|
||||
59
src/audio/InversionFrequency.java
Normal file
59
src/audio/InversionFrequency.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
/**
|
||||
* Standard voice inversion foldover frequencies
|
||||
*
|
||||
* Reference: http://en.wikipedia.org/wiki/Voice_inversion
|
||||
*/
|
||||
public enum InversionFrequency
|
||||
{
|
||||
HZ_2500( 2500 ),
|
||||
HZ_2550( 2550 ),
|
||||
HZ_2600( 2600 ),
|
||||
HZ_2632( 2632 ),
|
||||
HZ_2675( 2675 ),
|
||||
HZ_2718( 2718 ),
|
||||
HZ_2800( 2800 ),
|
||||
HZ_2868( 2868 ),
|
||||
HZ_2950( 2950 ),
|
||||
HZ_3023( 3023 ),
|
||||
HZ_3075( 3075 ),
|
||||
HZ_3107( 3107 ),
|
||||
HZ_3150( 3150 ),
|
||||
HZ_3196( 3196 ),
|
||||
HZ_3333( 3333 ),
|
||||
HZ_3339( 3339 ),
|
||||
HZ_3400( 3400 ),
|
||||
HZ_3496( 3496 ),
|
||||
HZ_3729( 3729 ),
|
||||
HZ_4096( 4096 );
|
||||
|
||||
private int mFrequency;
|
||||
|
||||
private InversionFrequency( int frequency )
|
||||
{
|
||||
mFrequency = frequency;
|
||||
}
|
||||
|
||||
public int getFrequency()
|
||||
{
|
||||
return mFrequency;
|
||||
}
|
||||
}
|
||||
31
src/audio/SquelchListener.java
Normal file
31
src/audio/SquelchListener.java
Normal file
@@ -0,0 +1,31 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 audio;
|
||||
|
||||
public interface SquelchListener
|
||||
{
|
||||
/**
|
||||
* Squelch Control:
|
||||
*/
|
||||
public void setSquelch( SquelchState state );
|
||||
|
||||
public enum SquelchState
|
||||
{
|
||||
UNSQUELCH, SQUELCH;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user