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

106 wiersze
4.1 KiB
Java
Czysty Zwykły widok Historia

package com.bg7yoz.ft8cn.icom;
/**
* IComAudioUdp
* @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);
}
}
}