Compare commits

...

1 Commits

Author SHA1 Message Date
Denny Sheirer
a53f6e9d99 #2628 Remove ThumbDV code support. (#2629)
Co-authored-by: denny <dennis.sheirer@gmail.com>
2026-11-12 05:18:52 -05:00
38 changed files with 10 additions and 3730 deletions

View File

@@ -109,7 +109,6 @@ dependencies {
implementation 'ch.qos.logback:logback-classic:1.6.6'
implementation 'ch.qos.logback:logback-core:1.6.6'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.23.0'
implementation 'com.fazecast:jSerialComm:2.11.4'
implementation 'com.formdev:flatlaf:3.8'
implementation 'com.formdev:flatlaf-intellij-themes:3.8' //Not imported - Theme.java loads these themes by class name
implementation 'com.github.jiconfont:jiconfont-font_awesome:4.7.0.1'
@@ -278,38 +277,17 @@ def configure(RuntimeZipTask rt, List<String> jvmArgs) {
rt.extension.imageZip.set(file(layout.buildDirectory.dir('image').get().file('sdr-trunk.zip')))
}
/**
* Native library folders to keep in each runtime target image, keyed by the target name prefix. The tuner libraries
* (jRTL, jAirspy, etc.) package their native libraries under '<library>/native/<os>-<arch>/' and jSerialComm packages
* them under '<OS>/<arch>/'. All other operating system and architecture folders are removed from the target image.
*/
def nativeFolders = [
'linux-aarch64' : [tuner: 'linux-aarch64', serial: 'Linux/armv8_64'],
'linux-x86_64' : [tuner: 'linux-x86_64', serial: 'Linux/x86_64'],
'osx-aarch64' : [tuner: 'macos-aarch64', serial: 'OSX/aarch64'],
'osx-x86_64' : [tuner: 'macos-x86_64', serial: 'OSX/x86_64'],
'windows-aarch64': [tuner: 'windows-aarch64', serial: 'Windows/aarch64'],
'windows-x86_64' : [tuner: 'windows-x86_64', serial: 'Windows/x86_64']
]
/**
* Top level folders that jSerialComm uses for its per-OS native libraries.
*/
def serialOsFolders = ['Android', 'FreeBSD', 'Linux', 'OpenBSD', 'OSX', 'Solaris', 'Windows'] as Set
/**
* Rewrites the jar file without the native library folders for other operating systems and architectures. Fails the
* build if a jar that contains native libraries doesn't contain the folder for the target.
* @param jar file to rewrite
* @param keep native folders for the target (tuner and serial)
* @param serialOsFolders jSerialComm top level OS folders
* @param keep native folder for the target
* @return number of bytes removed from the jar
*/
long stripJar(File jar, Map<String,String> keep, Set<String> serialOsFolders) {
long stripJar(File jar, String keep) {
def tunerPattern = ~/^[^\/]+\/native\/([^\/]+)\/.*/
def serialPrefix = keep.serial + '/'
def removed = [] as Set
def hadTuner = false, keptTuner = false, hadSerial = false, keptSerial = false
def hadTuner = false, keptTuner = false
File temp = new File(jar.parentFile, jar.name + '.tmp')
new java.util.zip.ZipFile(jar).withCloseable { zip ->
@@ -317,23 +295,15 @@ long stripJar(File jar, Map<String,String> keep, Set<String> serialOsFolders) {
entries.each { e ->
def tuner = tunerPattern.matcher(e.name)
def top = e.name.contains('/') ? e.name.substring(0, e.name.indexOf('/')) : null
if(tuner.matches()) {
hadTuner = true
if(tuner.group(1) == keep.tuner) { keptTuner = true } else { removed << e.name }
}
else if(top in serialOsFolders) {
hadSerial = true
if(e.name.startsWith(serialPrefix)) { keptSerial = true } else { removed << e.name }
if(tuner.group(1) == keep) { keptTuner = true } else { removed << e.name }
}
}
if(hadTuner && !keptTuner) {
throw new GradleException("Native strip: ${jar.name} has no native/${keep.tuner} folder")
}
if(hadSerial && !keptSerial) {
throw new GradleException("Native strip: ${jar.name} has no ${keep.serial} folder")
throw new GradleException("Native strip: ${jar.name} has no native/${keep} folder")
}
if(!removed.isEmpty()) {
@@ -362,21 +332,18 @@ long stripJar(File jar, Map<String,String> keep, Set<String> serialOsFolders) {
/**
* Removes the native libraries for other operating systems and architectures from the jars in each runtime target
* image, before the runtimeZip tasks package the images.
* image, before the runtimeZip tasks package the images. The tuner libraries (jRTL, jAirspy, etc.) package their
* native libraries under '<library>/native/<os>-<arch>/', where the folder name matches the runtime target name
* '<os>-<arch>-v<version>' without the version suffix, except that the libraries use 'macos' where the target uses 'osx'.
*/
tasks.named('runtime') {rt ->
rt.doLast {
rt.targetPlatforms.get().keySet().each { target ->
def key = nativeFolders.keySet().find { target.startsWith(it + '-') }
if(key == null) {
throw new GradleException("Native strip: no native folder mapping for runtime target [${target}]")
}
def nativeFolder = (target - "-v${version}").replaceFirst(/^osx-/, 'macos-')
def lib = new File(rt.imageDir.asFile, "${project.name}-${target}/lib")
long total = 0
lib.listFiles({ File f -> f.name.endsWith('.jar') } as FileFilter).each { jar ->
total += stripJar(jar, nativeFolders[key], serialOsFolders)
total += stripJar(jar, nativeFolder)
}
logger.lifecycle("Native strip: removed ${String.format('%.1f', total / 1048576)} MB of other " +
"platform native libraries from [${target}]")

File diff suppressed because it is too large Load Diff

View File

@@ -1,483 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 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.audio.convert.thumbdv;
import com.fazecast.jSerialComm.SerialPort;
import io.github.dsheirer.audio.convert.thumbdv.message.AmbeMessage;
import io.github.dsheirer.audio.convert.thumbdv.message.AmbeMessageFactory;
import io.github.dsheirer.audio.convert.thumbdv.message.VocoderRate;
import io.github.dsheirer.audio.convert.thumbdv.message.request.AmbeRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.request.DecodeSpeechRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.request.EncodeSpeechRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.request.ResetRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.request.SetVocoderParametersRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.request.SetVocoderRequest;
import io.github.dsheirer.audio.convert.thumbdv.message.response.DecodeSpeechResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.ReadyResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetVocoderParameterResponse;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.util.ThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* Northwest Digital Radio (NWDR) ThumbDv dongle.
*
* Note: linux users must allow access to the serial port:
*
* sudo usermod -a -G uucp username
* sudo usermod -a -G dialout username
* sudo usermod -a -G lock username
* sudo usermod -a -G tty username
*/
public class ThumbDv implements AutoCloseable
{
private final static Logger mLog = LoggerFactory.getLogger(ThumbDv.class);
private static final String PORT_DESCRIPTION = "USB-to-Serial Port (ftdi_sio)";
private static final String PORT_DESCRIPTION_FRAGMENT = "USB Serial Port";
private static final int BAUD_RATE = 460800;
private static final byte PACKET_START = (byte) 0x61;
public enum AudioProtocol
{
DMR,
DSTAR,
NXDN,
P25_PHASE2,
}
private SerialPort mSerialPort;
private ScheduledFuture mSerialPortReaderHandle;
private ScheduledFuture mAudioDecodeProcessorHandle;
private LinkedTransferQueue<DecodeSpeechRequest> mDecodeSpeechRequests = new LinkedTransferQueue<>();
private AudioProtocol mAudioProtocol;
private Listener<float[]> mAudioBufferListener;
private boolean mStarted;
public ThumbDv(AudioProtocol audioProtocol, Listener<float[]> listener)
{
mAudioProtocol = audioProtocol;
mAudioBufferListener = listener;
}
/**
* Enqueues the audio code frame for decoding. Decoded PCM speech packet will be sent to the registered
* audio packet listener.
*
* @param codecFrame
*/
public void decode(byte[] codecFrame)
{
if(!mStarted || mSerialPort == null)
{
throw new IllegalStateException("Must invoke start() method and thumbdv serial device must be available");
}
mDecodeSpeechRequests.offer(new DecodeSpeechRequest(codecFrame));
}
public void close() throws IOException
{
if(mSerialPortReaderHandle != null)
{
mSerialPortReaderHandle.cancel(true);
mSerialPortReaderHandle = null;
}
if(mSerialPort != null)
{
mSerialPort.closePort();
}
}
public void start() throws IOException
{
if(mSerialPort == null)
{
SerialPort[] ports = SerialPort.getCommPorts();
for(SerialPort port : ports)
{
mLog.debug("Serial Port Name:" + port.getDescriptivePortName());
if(port.getDescriptivePortName().contentEquals(PORT_DESCRIPTION) ||
port.getDescriptivePortName().contains(PORT_DESCRIPTION_FRAGMENT))
{
mSerialPort = port;
mSerialPort.setBaudRate(BAUD_RATE);
mSerialPort.openPort(0, 5000, 10000);
if(mSerialPort.isOpen())
{
mLog.info("Resetting ThumbDv Device");
send(new ResetRequest());
mLog.info("Creating Serial Port Reader");
final Runnable r = new SerialPortReader(mSerialPort.getInputStream());
mLog.info("Starting Serial Port Reader");
mSerialPortReaderHandle = ThreadPool.SCHEDULED.scheduleAtFixedRate(r, 0,
5, TimeUnit.MILLISECONDS);
mStarted = true;
mLog.info("Startup complete - awaiting reset response");
}
else
{
mLog.warn("Could not open serial port: " + mSerialPort.getSystemPortName());
throw new IOException("Could not open serial port:" + mSerialPort.getSystemPortName());
}
break;
}
}
}
if(mSerialPort == null)
{
throw new IOException("ThumbDV serial port not found");
}
return;
}
public void send(byte[] message) throws IOException
{
if(mSerialPort == null)
{
throw new IOException("ThumbDv must be started before use");
}
int bytesWritten = mSerialPort.writeBytes(message, message.length);
if(bytesWritten < 0)
{
throw new IOException("Unable to write message:" + Arrays.toString(message));
}
else if(bytesWritten != message.length)
{
throw new IOException("Unable to write message:" + Arrays.toString(message) + " Bytes Written:" + bytesWritten);
}
}
/**
* Sends the AMBE request message
*
* @param request message
* @throws IOException if there is an error
*/
public void send(AmbeRequest request) throws IOException
{
send(request.getData());
}
private void receive(byte[] bytes)
{
AmbeMessage message = AmbeMessageFactory.getMessage(bytes);
if(message instanceof DecodeSpeechResponse && mAudioBufferListener != null)
{
float[] samples = ((DecodeSpeechResponse)message).getSamples();
mAudioBufferListener.receive(samples);
}
else if(message instanceof ReadyResponse && mAudioDecodeProcessorHandle == null)
{
if(mAudioDecodeProcessorHandle == null)
{
try
{
switch(mAudioProtocol)
{
case DSTAR:
send(new SetVocoderRequest(VocoderRate.RATE_33));
send(new SetVocoderParametersRequest(0x0130, 0x0763, 0x4000, 0x0000, 0x0000, 0x0048));
break;
case DMR:
case NXDN:
case P25_PHASE2:
send(new SetVocoderRequest(VocoderRate.RATE_33));
send(new SetVocoderParametersRequest(0x0431, 0x0754, 0x2400, 0x0000, 0x0000, 0x6F48));
break;
default:
throw new IllegalStateException("Unrecognized audio protocol:" + mAudioProtocol);
}
}
catch(IOException ioe)
{
mLog.error("Error setting audio protocol vocoder parameters");
}
mLog.info("ThumbDv Reset Complete");
}
else
{
mLog.info("ThumbDv Reset Detected");
}
}
else if(message instanceof SetVocoderParameterResponse)
{
if(((SetVocoderParameterResponse)message).isSuccessful())
{
mLog.info("Audio vocoder parameters configured for " + mAudioProtocol);
//Start the audio frame decode processor
mAudioDecodeProcessorHandle = ThreadPool.SCHEDULED.scheduleAtFixedRate(new AudioDecodeProcessor(), 0,
10, TimeUnit.MILLISECONDS);
}
}
else if(message != null)
{
mLog.debug("RECEIVED:" + message.toString());
}
}
/**
* Logs the current settings of the serial port. Note: you must invoke start() before this method so that
* the serial port can be discovered and opened.
*/
public void logSerialPort()
{
if(mSerialPort != null)
{
StringBuilder sb = new StringBuilder();
sb.append("\nPort:\t\t\t").append(mSerialPort.getSystemPortName()).append("\n");
sb.append("Name:\t\t\t").append(mSerialPort.getDescriptivePortName()).append("\n");
sb.append("Baud Rate:\t\t").append(mSerialPort.getBaudRate()).append("\n");
sb.append("Data Bits:\t\t").append(mSerialPort.getNumDataBits()).append("\n");
sb.append("Parity Bits:\t").append(mSerialPort.getParity()).append("\n");
sb.append("Stop Bits:\t\t").append(mSerialPort.getNumStopBits()).append("\n");
sb.append("Flow Control:\t").append(mSerialPort.getFlowControlSettings()).append("\n");
sb.append("Is Open:\t\t").append(mSerialPort.isOpen()).append("\n");
mLog.info(sb.toString());
}
else
{
mLog.info("No serial port found");
}
}
/**
* Processes the audio frame decode queue
*/
public class AudioDecodeProcessor implements Runnable
{
@Override
public void run()
{
try
{
DecodeSpeechRequest request = mDecodeSpeechRequests.poll();
if(request != null)
{
try
{
send(request);
}
catch(IOException ioe)
{
mLog.error("Error decoding audio frame", ioe);
}
// try
// {
// //Force a 20ms sleep after submitting an audio frame to avoid overflowing the thumbdv
// Thread.sleep(20);
// }
// catch(InterruptedException ie)
// {
// //Do nothing
// }
}
}
catch(Throwable t)
{
mLog.error("Error", t);
}
}
}
public class SerialPortReader implements Runnable
{
private InputStream mInputStream;
public SerialPortReader(InputStream inputStream)
{
mInputStream = inputStream;
}
@Override
public void run()
{
try
{
if(mInputStream != null)
{
try
{
while(mInputStream.available() > 0)
{
byte[] buffer = new byte[400];
int bytesRead = mInputStream.readNBytes(buffer, 0, 1);
if(bytesRead == 1 && buffer[0] == PACKET_START)
{
while(mInputStream.available() < 2)
{
try
{
Thread.sleep(1);
}
catch(InterruptedException ie)
{
}
}
bytesRead = mInputStream.readNBytes(buffer, 1, 2);
if(bytesRead == 2)
{
int length = (0xFF & buffer[1]) << 8;
length += (0xFF & buffer[2]);
if(0 < length && length < 400)
{
length++; //Add a byte for the type byte
while(mInputStream.available() < length)
{
try
{
Thread.sleep(1);
}
catch(InterruptedException ie)
{
}
}
bytesRead = mInputStream.readNBytes(buffer, 3, length);
if(bytesRead == length)
{
receive(Arrays.copyOf(buffer, length + 3));
}
else
{
mLog.debug("Expected [" + length + "] but received [" + bytesRead + "] bytes - " + Arrays.toString(buffer));
}
}
else
{
mLog.error("Received packet with unexpected length: " + length);
//Don't process the buffer ... let the reader read and inspect 1 byte at a time
//to regain sync on the packet start byte
}
}
else
{
mLog.debug("Expected [2] but received [" + bytesRead + "] -- this shouldn't happen");
}
}
else
{
mLog.debug("Unrecognized byte: " + Arrays.toString(buffer));
}
}
}
catch(IOException ioe)
{
mLog.error("Error while reading ThumbDv serial port", ioe);
}
}
}
catch(Throwable t)
{
mLog.error("Error", t);
}
}
}
public static void main(String[] args)
{
mLog.debug("Starting");
String silence = "BEDDEA821EFD660C08";
String[] frames = {"0E46122323067C60F8", "0E469433C1067CF1BC", "0E46122B23067C60F8", "0E67162BE08874E2B4",
"0E46163BE1067CF1BC", "0E46122B23067C60F8", "0A06163BE00A5C303E", "0E46122B23067C60F8", "0E46163BE1847CE1FC",
"0E46122B23067C60F8"};
List<byte[]> frameData = new ArrayList<>();
for(String frame : frames)
{
byte[] bytes = new byte[frame.length() / 2];
for(int x = 0; x < frame.length(); x += 2)
{
String hex = frame.substring(x, x + 2);
bytes[x / 2] = (byte) (0xFF & Integer.parseInt(hex, 16));
}
frameData.add(bytes);
}
mLog.debug("Starting thumb dv thread(s)");
final Listener<float[]> listener = packet -> {
mLog.info("Got an audio packet!");
};
try(ThumbDv thumbDv = new ThumbDv(AudioProtocol.P25_PHASE2, listener))
{
thumbDv.start();
Thread.sleep(6000);
for(int x = 0; x < 20; x++)
{
thumbDv.send(new EncodeSpeechRequest(new short[160]));
Thread.sleep(20);
}
// for(byte[] frame : frameData)
// {
// thumbDv.decode(frame);
// }
while(true);
}
catch(IOException ioe)
{
mLog.error("Error", ioe);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}

View File

@@ -1,44 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message;
/**
* AMBE-3000R Message
*/
public abstract class AmbeMessage
{
/**
* Converts the byte array to a hexadecimal string array
*/
public static String toHex(byte[] data)
{
StringBuilder sb = new StringBuilder();
for(byte b: data)
{
sb.append(String.format("%02X", b));
}
return sb.toString();
}
}

View File

@@ -1,95 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message;
import io.github.dsheirer.audio.convert.thumbdv.message.response.DecodeSpeechResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.EncodeSpeechResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.GetConfigResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.InitializeCodecResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.ProductIdResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.ReadyResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetChannelFormatResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetChannelResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetPacketModeResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetSpeechFormatResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetVocoderParameterResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.SetVocoderResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.UnknownResponse;
import io.github.dsheirer.audio.convert.thumbdv.message.response.VersionResponse;
public class AmbeMessageFactory
{
private static final byte CONTROL_PACKET = (byte)0x00;
private static final byte CHANNEL_PACKET = (byte)0x01;
private static final byte SPEECH_PACKET = (byte)0x02;
private static final int INDEX_PACKET_TYPE = 3;
private static final int INDEX_CONTROL_PACKET_TYPE = 4;
public static AmbeMessage getMessage(byte[] data)
{
if(data != null && data.length >= 5)
{
if(data[INDEX_PACKET_TYPE] == CONTROL_PACKET)
{
PacketField packetField = PacketField.fromValue(data[INDEX_CONTROL_PACKET_TYPE]);
switch(packetField)
{
case PKT_CHANNEL_0:
return new SetChannelResponse(data);
case PKT_CHANNEL_FORMAT:
return new SetChannelFormatResponse(data);
case PKT_CODEC_STOP:
return new SetPacketModeResponse(data);
case PKT_GET_CONFIG:
return new GetConfigResponse(data);
case PKT_INIT:
return new InitializeCodecResponse(data);
case PKT_PRODUCT_ID:
return new ProductIdResponse(data);
case PKT_RATE_PARAMETER:
return new SetVocoderParameterResponse(data);
case PKT_RATE_TABLE:
return new SetVocoderResponse(data);
case PKT_READY:
return new ReadyResponse(data);
case PKT_SPEECH_FORMAT:
return new SetSpeechFormatResponse(data);
case PKT_VERSION_STRING:
return new VersionResponse(data);
}
}
else if(data[INDEX_PACKET_TYPE] == CHANNEL_PACKET)
{
return new EncodeSpeechResponse(data);
}
else if(data[INDEX_PACKET_TYPE] == SPEECH_PACKET)
{
return new DecodeSpeechResponse(data);
}
}
return new UnknownResponse(data);
}
}

View File

@@ -1,47 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message;
/**
* AMBE-3000 Initialization Options
*/
public enum InitializeOption
{
ENCODER((byte)0x01),
DECODER((byte)0x02),
ENCODER_AND_DECODER((byte)0x03),
ECHO_CANCELLER((byte)0x04),
ENCODER_DECODER_ECHO_CANCELLER((byte)0x07);
private byte mCode;
InitializeOption(byte code)
{
mCode = code;
}
public byte getCode()
{
return mCode;
}
}

View File

@@ -1,160 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 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.audio.convert.thumbdv.message;
/**
* AMBE-3000R Control Packet Field enumeration
*/
public enum PacketField
{
PKT_ENCODER_CMODE((byte)0x05),
PKT_DECODER_CMODE((byte)0x06),
PKT_RATE_TABLE((byte)0x09),
PKT_RATE_PARAMETER((byte)0x0A),
PKT_INIT((byte)0x0B),
PKT_LOW_POWER((byte)0x10),
PKT_CHANNEL_FORMAT((byte)0x15),
PKT_SPEECH_FORMAT((byte)0x16),
PKT_CODEC_START((byte)0x2A),
PKT_CODEC_STOP((byte)0x2B),
PKT_PRODUCT_ID((byte)0x30),
PKT_VERSION_STRING((byte)0x31),
PKT_COMPAND((byte)0x32),
PKT_RESET((byte)0x33),
PKT_RESET_TO_SOFTWARE_CONFIG((byte)0x34),
PKT_HALT((byte)0x35),
PKT_GET_CONFIG((byte)0x36),
PKT_READ_CONFIG((byte)0x37),
PKT_CODEC_CFG((byte)0x38),
PKT_READY((byte)0x39),
PKT_PARITY_MODE((byte)0x3F),
PKT_CHANNEL_0((byte)0x40),
PKT_WRITE_I2C((byte)0x44),
PKT_CLEAR_CODEC_RESET((byte)0x46),
PKT_SET_CODEC_RESET((byte)0x47),
PKT_DISCARD_CODEC_SAMPLES((byte)0x48),
PKT_DELAY_NUMBER_MICRO_SECONDS((byte)0x49),
PKT_DELAY_NUMBER_NANO_SECONDS((byte)0x4A),
PKT_GAIN((byte)0x4B),
PKT_RTS_THRESHOLD((byte)0x4E),
//Speech packet values
SPEECH_DATA((byte)0x00),
CHANNEL_DATA_HARD_SYMBOL((byte)0x01),
CMODE((byte)0x02),
SAMPLE_COUNT((byte)0x03),
TONE((byte)0x08),
CHANNEL_DATA_SOFT_SYMBOL((byte)0x17),
VOCODER((byte)0x40),
//Packet Types
PACKET_TYPE_CONTROL((byte)0x00),
PACKET_TYPE_ENCODE_SPEECH((byte)0x01),
PACKET_TYPE_DECODE_SPEECH((byte)0x02),
UNKNOWN((byte)0x00);
private byte mCode;
PacketField(byte code)
{
mCode = code;
}
/**
* Packet type byte code value
*/
public byte getCode()
{
return mCode;
}
/**
* Lookup a packet type from the code byte value
*/
public static PacketField fromValue(byte value)
{
switch(value)
{
case (byte)0x05:
return PKT_ENCODER_CMODE;
case (byte)0x06:
return PKT_DECODER_CMODE;
case (byte)0x09:
return PKT_RATE_TABLE;
case (byte)0x0A:
return PKT_RATE_PARAMETER;
case (byte)0x0B:
return PKT_INIT;
case (byte)0x10:
return PKT_LOW_POWER;
case (byte)0x15:
return PKT_CHANNEL_FORMAT;
case (byte)0x16:
return PKT_SPEECH_FORMAT;
case (byte)0x2A:
return PKT_CODEC_START;
case (byte)0x2B:
return PKT_CODEC_STOP;
case (byte)0x30:
return PKT_PRODUCT_ID;
case (byte)0x31:
return PKT_VERSION_STRING;
case (byte)0x32:
return PKT_COMPAND;
case (byte)0x33:
return PKT_RESET;
case (byte)0x34:
return PKT_RESET_TO_SOFTWARE_CONFIG;
case (byte)0x35:
return PKT_HALT;
case (byte)0x36:
return PKT_GET_CONFIG;
case (byte)0x37:
return PKT_READ_CONFIG;
case (byte)0x38:
return PKT_CODEC_CFG;
case (byte)0x39:
return PKT_READY;
case (byte)0x3F:
return PKT_PARITY_MODE;
case (byte)0x40:
return PKT_CHANNEL_0;
case (byte)0x44:
return PKT_WRITE_I2C;
case (byte)0x46:
return PKT_CLEAR_CODEC_RESET;
case (byte)0x47:
return PKT_SET_CODEC_RESET;
case (byte)0x48:
return PKT_DISCARD_CODEC_SAMPLES;
case (byte)0x49:
return PKT_DELAY_NUMBER_MICRO_SECONDS;
case (byte)0x4A:
return PKT_DELAY_NUMBER_NANO_SECONDS;
case (byte)0x4B:
return PKT_GAIN;
case (byte)0x4E:
return PKT_RTS_THRESHOLD;
default:
return UNKNOWN;
}
}
}

View File

@@ -1,129 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message;
public enum VocoderRate
{
//AMBE-1000 Standard Rates
RATE_0((byte)0x00, 2400,0),
RATE_1((byte)0x01, 3600,0),
RATE_2((byte)0x02, 3600,1200),
RATE_3((byte)0x03, 4800,0),
RATE_4((byte)0x04, 9600,0),
RATE_5((byte)0x05, 2350,50),
RATE_6((byte)0x06, 4850,4750),
RATE_7((byte)0x07, 4550,250),
RATE_8((byte)0x08, 3100,1700),
RATE_9((byte)0x09, 4400,2800),
RATE_10((byte)0x0A, 4150,2250),
RATE_11((byte)0x0B, 3350,250),
RATE_12((byte)0x0C, 7750,250),
RATE_13((byte)0x0D, 4650,3350),
RATE_14((byte)0x0E, 3750,250),
RATE_15((byte)0x0F, 4000,0),
//AMBE-2000 Standard Rates
RATE_16((byte)0x10, 3600,0),
RATE_17((byte)0x11, 4000,0),
RATE_18((byte)0x12, 4800,0),
RATE_19((byte)0x13, 6400,0),
RATE_20((byte)0x14, 8000,0),
RATE_21((byte)0x15, 9600,0),
RATE_22((byte)0x16, 2400,1600),
RATE_23((byte)0x17, 3600,1200),
RATE_24((byte)0x18, 4000,800),
RATE_25((byte)0x19, 2400,2400),
RATE_26((byte)0x1A, 4000,2400),
RATE_27((byte)0x1B, 4400,2800), //Is this compatible with APCO25 Phase 1?
RATE_28((byte)0x1C, 4000,4000),
RATE_29((byte)0x1D, 2400,7200),
RATE_30((byte)0x1E, 3600,6000),
RATE_31((byte)0x1F, 2000,0),
RATE_32((byte)0x20, 3600,2800),
//AMBE-3000 Standard Rates (AMBE+2)
RATE_33((byte)0x21, 2450,1150), //APCO25 HR (Phase 2), DMR, NXDN, DSTAR
RATE_34((byte)0x22, 2450,0),
RATE_35((byte)0x23, 2250,1150),
RATE_36((byte)0x24, 2250,0),
RATE_37((byte)0x25, 2400,0),
RATE_38((byte)0x26, 3000,0),
RATE_39((byte)0x27, 3600,0),
RATE_40((byte)0x28, 4000,0),
RATE_41((byte)0x29, 4400,0),
RATE_42((byte)0x2A, 4800,0),
RATE_43((byte)0x2B, 6400,0),
RATE_44((byte)0x2C, 7200,0),
RATE_45((byte)0x2D, 8000,0),
RATE_46((byte)0x2E, 9600,0),
RATE_47((byte)0x2F, 2450,250),
RATE_48((byte)0x30, 3350,250),
RATE_49((byte)0x31, 3750,250),
RATE_50((byte)0x32, 4550,250),
RATE_51((byte)0x33, 2450,1950),
RATE_52((byte)0x34, 2450,2350),
RATE_53((byte)0x35, 2450,3550),
RATE_54((byte)0x36, 2450,4750),
RATE_55((byte)0x37, 2600,1400),
RATE_56((byte)0x38, 3600,1200),
RATE_57((byte)0x39, 4000,800),
RATE_58((byte)0x3A, 4000,2400),
RATE_59((byte)0x3B, 4400,2800), //Is this compatible with APCO25 Phase 1?
RATE_60((byte)0x3C, 4000,4000),
RATE_61((byte)0x3D, 3600,6000);
private byte mCode;
private int mSpeechRate;
private int mFecRate;
VocoderRate(byte code, int speechRate, int fecRate)
{
mCode = code;
mSpeechRate = speechRate;
mFecRate = fecRate;
}
/**
* Byte code value for the vocoder rate
*/
public byte getCode()
{
return mCode;
}
/**
* Speech rate in bits per second (bps)
*/
public int getSpeechRate()
{
return mSpeechRate;
}
/**
* Forward Error Correction rate in bits per second (bps)
*/
public int getFecRate()
{
return mFecRate;
}
}

View File

@@ -1,67 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.AmbeMessage;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* AMBE-3000R Request Packet
*/
public abstract class AmbeRequest extends AmbeMessage
{
private static final byte PACKET_START_BYTE = (byte)0x61;
protected static final int PACKET_TYPE_INDEX = 3;
protected static final int PAYLOAD_START_INDEX = 4;
public abstract PacketField getType();
public abstract byte[] getData();
/**
* Creates a byte array of the specified length plus 4 packet header bytes with packet start, length and control
* bytes filled in.
*
* @param length of the message (not including the 4 byte packet header)
* @return byte array with packet header pre-filled.
*/
protected byte[] createMessage(int length, PacketField type)
{
byte[] data = new byte[length + 4];
data[0] = PACKET_START_BYTE;
data[1] = (byte)((length >> 8 & 0xFF));
data[2] = (byte)(length & 0xFF);
if(type == PacketField.PACKET_TYPE_ENCODE_SPEECH || type == PacketField.PACKET_TYPE_DECODE_SPEECH)
{
data[PACKET_TYPE_INDEX] = type.getCode();
}
else
{
data[PACKET_TYPE_INDEX] = PacketField.PACKET_TYPE_CONTROL.getCode();
data[PAYLOAD_START_INDEX] = type.getCode();
}
return data;
}
}

View File

@@ -1,108 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import io.github.dsheirer.audio.convert.thumbdv.message.VocoderRate;
/**
* Decode speech request, used to request decode of an encoded audio frame.
*/
public class DecodeSpeechRequest extends AmbeRequest
{
private static final int CHANNEL_DATA_IDENTIFIER_INDEX = 4;
private static final byte SAMPLE_COUNT = (byte)(0xFF & 160); //8 kHz Audio sample count for 20ms frame
private byte[] mAudioFrame;
private VocoderRate mVocoderRate;
/**
* Constructs an audio frame decode request using the specified vocoder rate.
* @param audioFrame of encoded audio samples
* @param vocoderRate to use when decoding
*/
public DecodeSpeechRequest(byte[] audioFrame, VocoderRate vocoderRate)
{
mAudioFrame = audioFrame;
mVocoderRate = vocoderRate;
}
/**
* Constructs an audio frame decode request using the current vocoder rate.
* @param audioFrame of encoded audio samples
*/
public DecodeSpeechRequest(byte[] audioFrame)
{
this(audioFrame, null);
}
@Override
public PacketField getType()
{
return PacketField.PACKET_TYPE_ENCODE_SPEECH;
}
private boolean hasVocoderRate()
{
return mVocoderRate != null;
}
@Override
public byte[] getData()
{
if(hasVocoderRate())
{
int length = mAudioFrame.length + 9;
byte[] data = createMessage(length, getType());
int offset = CHANNEL_DATA_IDENTIFIER_INDEX;
data[offset++] = PacketField.VOCODER.getCode();
data[offset++] = mVocoderRate.getCode();
data[offset++] = PacketField.CHANNEL_DATA_HARD_SYMBOL.getCode();
data[offset++] = (byte)(0xFF & (mAudioFrame.length * 8));
System.arraycopy(mAudioFrame, 0, data, offset, mAudioFrame.length);
offset += mAudioFrame.length;
data[offset++] = PacketField.SAMPLE_COUNT.getCode();
data[offset++] = (byte)0xA0;
data[offset++] = (byte)0x02;
data[offset++] = (byte)0x00;
data[offset] = (byte)0x00;
return data;
}
else
{
int length = mAudioFrame.length + 2;
byte[] data = createMessage(length, getType());
int offset = CHANNEL_DATA_IDENTIFIER_INDEX;
data[offset++] = PacketField.CHANNEL_DATA_HARD_SYMBOL.getCode();
data[offset++] = (byte)(0xFF & (mAudioFrame.length * 8));
System.arraycopy(mAudioFrame, 0, data, offset, mAudioFrame.length);
return data;
}
}
}

View File

@@ -1,88 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
public class EncodeSpeechRequest extends AmbeRequest
{
private static final int CHANNEL_IDENTIFIER_INDEX = 4;
private static final int SPEECH_DATA_IDENTIFIER_INDEX = 5;
private static final int SAMPLE_COUNT_INDEX = 6;
private static final int SPEECH_DATA_START_INDEX = 7;
private short[] mSamples;
public EncodeSpeechRequest(short[] samples)
{
mSamples = samples;
}
public EncodeSpeechRequest(float[] samples)
{
mSamples = new short[samples.length];
for(int x = 0; x < samples.length; x++)
{
if(samples[x] > 1.0f)
{
mSamples[x] = Short.MAX_VALUE;
}
else if(samples[x] < -1.0f)
{
mSamples[x] = Short.MIN_VALUE;
}
else
{
mSamples[x] = (short)(samples[x] * Short.MAX_VALUE);
}
}
}
@Override
public PacketField getType()
{
return PacketField.PACKET_TYPE_DECODE_SPEECH;
}
@Override
public byte[] getData()
{
int length = (mSamples.length * 2) + 3;
byte[] data = createMessage(length, getType());
data[CHANNEL_IDENTIFIER_INDEX] = PacketField.PKT_CHANNEL_0.getCode();
data[SPEECH_DATA_IDENTIFIER_INDEX] = (byte)0x00;
data[SAMPLE_COUNT_INDEX] = (byte)(0xFF & mSamples.length);
int pointer = SPEECH_DATA_START_INDEX;
for(short sample: mSamples)
{
data[pointer++] = (byte)((sample >> 8 & 0xFF));
data[pointer++] = (byte)(sample & 0xFF);
}
return data;
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Get configuration request packet
*/
public class GetConfigRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_GET_CONFIG;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,54 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.InitializeOption;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Initialize CODEC request packet
*/
public class InitializeCodecRequest extends AmbeRequest
{
private static final int INITIALIZE_OPTION_INDEX = 5;
private InitializeOption mInitializeOption;
public InitializeCodecRequest(InitializeOption option)
{
mInitializeOption = option;
}
@Override
public PacketField getType()
{
return PacketField.PKT_INIT;
}
@Override
public byte[] getData()
{
byte[] data = createMessage(2, getType());
data[INITIALIZE_OPTION_INDEX] = mInitializeOption.getCode();
return data;
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Product ID request packet
*/
public class ProductIdRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_PRODUCT_ID;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Reset request packet
*/
public class ResetRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_RESET;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,48 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set channel format request packet
*/
public class SetChannelFormatRequest extends AmbeRequest
{
private static final int FORMAT_INDEX = 5;
private static final byte FORMAT = (byte)0x00;
@Override
public PacketField getType()
{
return PacketField.PKT_CHANNEL_FORMAT;
}
@Override
public byte[] getData()
{
byte[] data = createMessage(2, getType());
data[FORMAT_INDEX] = FORMAT;
return data;
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set channel request packet
*/
public class SetChannelRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_CHANNEL_0;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Packet mode (versus CODEC mode) request packet
*/
public class SetPacketModeRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_CODEC_STOP;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,48 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set speech format request packet
*/
public class SetSpeechFormatRequest extends AmbeRequest
{
private static final int FORMAT_INDEX = 5;
private static final byte FORMAT = (byte)0x00;
@Override
public PacketField getType()
{
return PacketField.PKT_SPEECH_FORMAT;
}
@Override
public byte[] getData()
{
byte[] data = createMessage(2, getType());
data[FORMAT_INDEX] = FORMAT;
return data;
}
}

View File

@@ -1,74 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set Vocoder parameters request packet
*/
public class SetVocoderParametersRequest extends AmbeRequest
{
private int mWord0;
private int mWord1;
private int mWord2;
private int mWord3;
private int mWord4;
private int mWord5;
public SetVocoderParametersRequest(int word0, int word1, int word2, int word3, int word4, int word5)
{
mWord0 = word0;
mWord1 = word1;
mWord2 = word2;
mWord3 = word3;
mWord4 = word4;
mWord5 = word5;
}
@Override
public PacketField getType()
{
return PacketField.PKT_RATE_PARAMETER;
}
@Override
public byte[] getData()
{
byte[] data = createMessage(14, getType());
data[PAYLOAD_START_INDEX + 1] = (byte)(mWord0 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 2] = (byte)(mWord0 & 0xFF);
data[PAYLOAD_START_INDEX + 3] = (byte)(mWord1 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 4] = (byte)(mWord1 & 0xFF);
data[PAYLOAD_START_INDEX + 5] = (byte)(mWord2 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 6] = (byte)(mWord2 & 0xFF);
data[PAYLOAD_START_INDEX + 7] = (byte)(mWord3 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 8] = (byte)(mWord3 & 0xFF);
data[PAYLOAD_START_INDEX + 9] = (byte)(mWord4 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 10] = (byte)(mWord4 & 0xFF);
data[PAYLOAD_START_INDEX + 11] = (byte)(mWord5 >> 8 & 0xFF);
data[PAYLOAD_START_INDEX + 12] = (byte)(mWord5 & 0xFF);
return data;
}
}

View File

@@ -1,53 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import io.github.dsheirer.audio.convert.thumbdv.message.VocoderRate;
/**
* Set Vocoder Rate request packet
*/
public class SetVocoderRequest extends AmbeRequest
{
private VocoderRate mVocoderRate;
public SetVocoderRequest(VocoderRate rate)
{
mVocoderRate = rate;
}
@Override
public PacketField getType()
{
return PacketField.PKT_RATE_TABLE;
}
@Override
public byte[] getData()
{
byte[] data = createMessage(2, getType());
data[PAYLOAD_START_INDEX + 1] = mVocoderRate.getCode();
return data;
}
}

View File

@@ -1,43 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.request;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Version string request packet
*/
public class VersionRequest extends AmbeRequest
{
@Override
public PacketField getType()
{
return PacketField.PKT_VERSION_STRING;
}
@Override
public byte[] getData()
{
return createMessage(1, getType());
}
}

View File

@@ -1,60 +0,0 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2022 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.AmbeMessage;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import java.util.Arrays;
/**
* AMBE-3000R Response Packet
*/
public abstract class AmbeResponse extends AmbeMessage
{
protected static final int PAYLOAD_START_INDEX = 5;
private byte[] mMessage;
protected AmbeResponse(byte[] message)
{
mMessage = message;
}
/**
* Control packet type
*/
public abstract PacketField getType();
/**
* Received message bytes
*/
protected byte[] getMessage()
{
return mMessage;
}
/**
* Payload of the packet (does not include the packet header)
*/
protected byte[] getPayload()
{
return Arrays.copyOfRange(getMessage(), PAYLOAD_START_INDEX, getMessage().length);
}
}

View File

@@ -1,59 +0,0 @@
/*******************************************************************************
* sdr-trunk
* Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import io.github.dsheirer.sample.ConversionUtils;
import java.util.Arrays;
/**
* Decode speech response
*/
public class DecodeSpeechResponse extends AmbeResponse
{
public DecodeSpeechResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PACKET_TYPE_DECODE_SPEECH;
}
/**
* Payload of the packet (does not include the packet header)
*/
protected byte[] getPayload()
{
return Arrays.copyOfRange(getMessage(), PAYLOAD_START_INDEX + 1, getMessage().length);
}
public float[] getSamples()
{
return ConversionUtils.convertFromSigned16BitSamples(getPayload());
}
@Override
public String toString()
{
return "DECODED SPEECH: SAMPLE COUNT:" + getSamples().length + " " + toHex(getPayload());
}
}

View File

@@ -1,59 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import java.util.Arrays;
/**
* Encode speech response
*/
public class EncodeSpeechResponse extends AmbeResponse
{
public EncodeSpeechResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PACKET_TYPE_ENCODE_SPEECH;
}
/**
* Payload of the packet (does not include the packet header)
*/
protected byte[] getPayload()
{
return Arrays.copyOfRange(getMessage(), PAYLOAD_START_INDEX + 1, getMessage().length);
}
@Override
public String toString()
{
return "ENCODED SPEECH: " + toHex(getPayload()) + " " + Arrays.toString(getMessage());
}
}

View File

@@ -1,49 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Get configuration response
*/
public class GetConfigResponse extends AmbeResponse
{
public GetConfigResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_GET_CONFIG;
}
@Override
public String toString()
{
return "CONFIGURATION: " + toHex(getPayload());
}
}

View File

@@ -1,58 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Initialize CODEC response
*/
public class InitializeCodecResponse extends AmbeResponse
{
public InitializeCodecResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_INIT;
}
/**
* Success / fail
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "INITIALIZE CODEC " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,56 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Product ID Response
*/
public class ProductIdResponse extends AmbeResponse
{
public ProductIdResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_PRODUCT_ID;
}
/**
* Product ID string
*/
public String getProductId()
{
return new String(getPayload()).trim();
}
@Override
public String toString()
{
return "PRODUCT ID:" + getProductId();
}
}

View File

@@ -1,50 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import java.util.Arrays;
/**
* Ready response
*/
public class ReadyResponse extends AmbeResponse
{
public ReadyResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_READY;
}
@Override
public String toString()
{
return "READY" + Arrays.toString(getMessage());
}
}

View File

@@ -1,57 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Reset response
*/
public class ResetResponse extends AmbeResponse
{
public ResetResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_RESET;
}
/**
* Success indicator
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "RESET " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,58 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set channel format response
*/
public class SetChannelFormatResponse extends AmbeResponse
{
public SetChannelFormatResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_CHANNEL_FORMAT;
}
/**
* Success or fail
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "SET CHANNEL FORMAT " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,57 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set Vocoder rate response
*/
public class SetChannelResponse extends AmbeResponse
{
public SetChannelResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_CHANNEL_0;
}
/**
* Success indicator
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "SET CHANNEL 0 " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,58 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set packet mode response
*/
public class SetPacketModeResponse extends AmbeResponse
{
public SetPacketModeResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_CODEC_STOP;
}
/**
* Success or fail
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "SET PACKET MODE " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,58 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set speech format response
*/
public class SetSpeechFormatResponse extends AmbeResponse
{
public SetSpeechFormatResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_SPEECH_FORMAT;
}
/**
* Success or fail
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "SET SPEECH FORMAT " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,65 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set Vocoder parameter response
*/
public class SetVocoderParameterResponse extends AmbeResponse
{
public SetVocoderParameterResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_RATE_PARAMETER;
}
/**
* Success indicator
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==3 && payload[0] == 0;
}
@Override
public String toString()
{
if(isSuccessful())
{
return "SET VOCODER RATE SUCCESSFUL";
}
else
{
return "SET VOCODER RATE **FAILED** - RESPONSE:" + toHex(getPayload());
}
}
}

View File

@@ -1,58 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Set Vocoder rate response
*/
public class SetVocoderResponse extends AmbeResponse
{
public SetVocoderResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_RATE_TABLE;
}
/**
* Success indicator
*/
public boolean isSuccessful()
{
byte[] payload = getPayload();
return payload != null && payload.length ==1 && payload[0] == 0;
}
@Override
public String toString()
{
return "SET VOCODER RATE " + (isSuccessful() ? "SUCCESSFUL" : "**FAILED**");
}
}

View File

@@ -1,50 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
import java.util.Arrays;
/**
* Unknown Response Message
*/
public class UnknownResponse extends AmbeResponse
{
public UnknownResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.UNKNOWN;
}
@Override
public String toString()
{
return "UNKNOWN MESSAGE:" + Arrays.toString(getMessage());
}
}

View File

@@ -1,56 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.audio.convert.thumbdv.message.response;
import io.github.dsheirer.audio.convert.thumbdv.message.PacketField;
/**
* Version Response
*/
public class VersionResponse extends AmbeResponse
{
public VersionResponse(byte[] message)
{
super(message);
}
@Override
public PacketField getType()
{
return PacketField.PKT_VERSION_STRING;
}
/**
* Version string
*/
public String getVersion()
{
return new String(getPayload()).trim();
}
@Override
public String toString()
{
return "VERSION:" + getVersion();
}
}