gpt4 book ai didi

java - 如何使用二进制数组 WebSocket 创建 TargetDataLine?

转载 作者:行者123 更新时间:2023-11-30 07:53:09 28 4
gpt4 key购买 nike

我创建了一个字节数组 WebSocket,它从客户端麦克风 ( navigator.getUserMedia ) 实时接收音频 block 。经过一段时间 WebSocket 停止接收新的字节数组后,我已经将此流记录到服务器中的 WAV 文件中。下面的代码代表了当前的情况。

WebSocket

@OnMessage
public void message(byte[] b) throws IOException{
if(byteOutputStream == null) {
byteOutputStream = new ByteArrayOutputStream();
byteOutputStream.write(b);
} else {
byteOutputStream.write(b);
}
}

存储WAV文件的线程

public void store(){
byte b[] = byteOutputStream.toByteArray();
try {
AudioFormat audioFormat = new AudioFormat(44100, 16, 1, true, true);
ByteArrayInputStream byteStream = new ByteArrayInputStream(b);
AudioInputStream audioStream = new AudioInputStream(byteStream, audioFormat, b.length);
DateTime date = new DateTime();
File file = new File("/tmp/"+date.getMillis()+ ".wav");
AudioSystem.write(audioStream, AudioFileFormat.Type.WAVE, file);
audioStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}

但我使用此 WebSocket 的目标不是录制 WAV 文件,而是使用 YIN pitch detection algorithm 实时处理音频。实现于 TarsosDSP图书馆。换句话说,这基本上就是执行PitchDetectorExample ,但使用来自 WebSocket 的数据而不是默认音频设备(操作系统麦克风)。下面的代码表示PitchDetectorExample如何当前正在使用操作系统提供的麦克风线初始化实时音频处理。

private void setNewMixer(Mixer mixer) throws LineUnavailableException, UnsupportedAudioFileException {      
if(dispatcher!= null){
dispatcher.stop();
}
currentMixer = mixer;
float sampleRate = 44100;
int bufferSize = 1024;
int overlap = 0;
final AudioFormat format = new AudioFormat(sampleRate, 16, 1, true, true);
final DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line;
line = (TargetDataLine) mixer.getLine(dataLineInfo);
final int numberOfSamples = bufferSize;
line.open(format, numberOfSamples);
line.start();
final AudioInputStream stream = new AudioInputStream(line);
JVMAudioInputStream audioStream = new JVMAudioInputStream(stream);
// create a new dispatcher
dispatcher = new AudioDispatcher(audioStream, bufferSize, overlap);
// add a processor
dispatcher.addAudioProcessor(new PitchProcessor(algo, sampleRate, bufferSize, this));
new Thread(dispatcher,"Audio dispatching").start();
}

有一种方法可以将 WebSocket 数据作为 TargetDataLine 处理,因此可以将其与 AudioDispatcher 连接起来。和 PitchProcessor ?不知何故,我需要将从 WebSocket 接收到的字节数组发送到音频处理线程。

欢迎提出有关如何实现这一目标的其他想法。谢谢!

最佳答案

我不确定您是否需要音频调度程序。如果你知道字节是如何编码的(PCM,16位单声道?),那么你可以将它们实时转换为浮点并将它们提供给音调检测器算法,在你的websocket中你可以做这样的事情(并且忘记输入流和音频调度程序):

 int index;
byte[] buffer = new byte[2048];
float[] floatBuffer = new float[1024];
FastYin detector = new FastYin(44100,1024);
public void message(byte[] b){
for(int i = 0 ; i < b.length; i++){
buffer[index] = b[i];
index++
if(index==2048){
AudioFloatConverter converter = AudioFloatConverter.getConverter(new Format(16bits, little endian, mono,...));
//converts the byte buffer to float
converter.toFloatArray(buffer,floatBuffer);
float pitch = detector.getPitch(floatBuffer);
//here you have your pitch info that you can use
index = 0;
}
}

您确实需要观察已传递的字节数:因为两个字节代表一个浮点(如果使用 16 位 pcm 编码),您需要从偶数字节开始。字节序和采样率也很重要。

问候

乔伦

关于java - 如何使用二进制数组 WebSocket 创建 TargetDataLine?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33061443/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com