FT8CN/ft8cn/app/src/main/java/com/bg7yoz/ft8cn/icom/IcomAudioUdp.java

106 wiersze
4.1 KiB
Java
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.bg7yoz.ft8cn.icom;
/**
* 处理ICom的音频流继承至AudioUdp。
* @author BGY70Z
* @date 2023-08-26
*/
import android.util.Log;
import com.bg7yoz.ft8cn.GeneralVariables;
import java.net.DatagramPacket;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class IcomAudioUdp extends AudioUdp {
private static final String TAG = "IcomAudioUdp";
private final ExecutorService doTXThreadPool =Executors.newCachedThreadPool();
private final DoTXAudioRunnable doTXAudioRunnable=new DoTXAudioRunnable(this);
@Override
public void sendTxAudioData(float[] audioData) {
if (audioData==null) return;
short[] temp=new short[audioData.length];
//传递过来的音频是LPCM,32 float12000Hz
//iCOM的音频格式是LPCM 16 Int12000Hz
//要做一下浮点到16位int的转换
for (int i = 0; i < audioData.length; i++) {
float x = audioData[i];
if (x > 1.0)
x = 1.0f;
else if (x < -1.0)
x = -1.0f;
temp[i] = (short) (x * 32767.0);
}
doTXAudioRunnable.audioData=temp;
doTXThreadPool.execute(doTXAudioRunnable);
}
private static class DoTXAudioRunnable implements Runnable{
IcomAudioUdp icomAudioUdp;
short[] audioData;//传递过来的音频是LPCM 16bit Int,12000hz
public DoTXAudioRunnable(IcomAudioUdp icomAudioUdp) {
this.icomAudioUdp = icomAudioUdp;
}
@Override
public void run() {
if (audioData==null) return;
final int partialLen = IComPacketTypes.TX_BUFFER_SIZE * 2;//数据包的长度
//要转换一下到BYTE,小端模式
//byte[] data = new byte[audioData.length * 2 + partialLen * 4];//多出一点空声音放在前后各20ms*2共80ms
//先播放是给出空的声音for i 循环做了一个判断是给前面的空声音for j循环做得判断是让后面发送空声音
byte[] audioPacket = new byte[partialLen];
for (int i = 0; i < (audioData.length / IComPacketTypes.TX_BUFFER_SIZE) + 8; i++) {//多出6个周期前面3个后面3个多
if (!icomAudioUdp.isPttOn) break;
long now = System.currentTimeMillis() - 1;//获取当前时间
icomAudioUdp.sendTrackedPacket(IComPacketTypes.AudioPacket.getTxAudioPacket(audioPacket
, (short) 0, icomAudioUdp.localId, icomAudioUdp.remoteId, icomAudioUdp.innerSeq));
icomAudioUdp.innerSeq++;
Arrays.fill(audioPacket,(byte)0x00);
if (i>=3) {//让前两个空数据发送出去
for (int j = 0; j < IComPacketTypes.TX_BUFFER_SIZE; j++) {
if ((i-3) * IComPacketTypes.TX_BUFFER_SIZE + j < audioData.length) {
System.arraycopy(IComPacketTypes.shortToBigEndian((short)
(audioData[(i-3) * IComPacketTypes.TX_BUFFER_SIZE + j]
* GeneralVariables.volumePercent))//乘以信号量的比率
, 0, audioPacket, j * 2, 2);
}
}
}
while (icomAudioUdp.isPttOn) {
if (System.currentTimeMillis() - now >= 21) {//20毫秒一个周期
break;
}
}
}
Log.d(TAG, "run: 音频发送完毕!!" );
Thread.currentThread().interrupt();
}
}
@Override
public void onDataReceived(DatagramPacket packet, byte[] data) {
super.onDataReceived(packet, data);
//接收到的是12000采样率的数据
if (!IComPacketTypes.AudioPacket.isAudioPacket(data)) return;
byte[] audioData = IComPacketTypes.AudioPacket.getAudioData(data);
if (onStreamEvents != null) {
onStreamEvents.OnReceivedAudioData(audioData);
}
}
}