From 6c51273c6e0bfb18754f01e9e4c4a44a607e4b39 Mon Sep 17 00:00:00 2001 From: zedoCN Date: Sat, 31 Aug 2024 05:12:34 +0800 Subject: [PATCH] =?UTF-8?q?=E7=84=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VoiceChat.iml | 1 + src/Client.kt | 3 -- src/Program.java | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 src/Program.java diff --git a/VoiceChat.iml b/VoiceChat.iml index 4ebda9a..1959666 100644 --- a/VoiceChat.iml +++ b/VoiceChat.iml @@ -12,5 +12,6 @@ + \ No newline at end of file diff --git a/src/Client.kt b/src/Client.kt index bb75514..5dbe528 100644 --- a/src/Client.kt +++ b/src/Client.kt @@ -26,7 +26,6 @@ var `in`: InputStream? = null var out: OutputStream? = null -var file = Files.newOutputStream(Path.of("./a.pcm")) object Client { @JvmStatic @@ -73,8 +72,6 @@ fun mainClient() = runBlocking { } `in`!!.read(bufferIn, 0, bufferIn.size) - file.write(bufferIn, 0, bufferIn.size) - file.flush() sourceDataLine.write(bufferIn, 0, bufferIn.size) } catch (e: IOException) { e.printStackTrace() diff --git a/src/Program.java b/src/Program.java new file mode 100644 index 0000000..fb283e2 --- /dev/null +++ b/src/Program.java @@ -0,0 +1,118 @@ +import io.github.jaredmdobson.concentus.*; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/** + * @author lostromb + */ +public class Program { + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + test(); + } + + public static void test() { + try { + FileInputStream fileIn = new FileInputStream("a.pcm"); + OpusEncoder encoder = new OpusEncoder(48000, 1, OpusApplication.OPUS_APPLICATION_AUDIO); + encoder.setBitrate(96000); + encoder.setForceMode(OpusMode.MODE_CELT_ONLY); + encoder.setSignalType(OpusSignal.OPUS_SIGNAL_MUSIC); + encoder.setComplexity(0); + + OpusDecoder decoder = new OpusDecoder(48000, 1); + + FileOutputStream fileOut = new FileOutputStream("b.pcm"); + int packetSamples = 960; + byte[] inBuf = new byte[packetSamples * 2 * 2]; + byte[] data_packet = new byte[1275]; + long start = System.currentTimeMillis(); + long size = 0; + while (fileIn.available() >= inBuf.length) { + int bytesRead = fileIn.read(inBuf, 0, inBuf.length); + short[] pcm = BytesToShorts(inBuf, 0, inBuf.length); + int bytesEncoded = encoder.encode(pcm, 0, packetSamples, data_packet, 0, 1275); + //System.out.println(bytesEncoded + " bytes encoded"); + + size += bytesEncoded; + + int samplesDecoded = decoder.decode(data_packet, 0, bytesEncoded, pcm, 0, packetSamples, false); + //System.out.println(samplesDecoded + " samples decoded"); + byte[] bytesOut = ShortsToBytes(pcm); + fileOut.write(bytesOut, 0, bytesOut.length); + } + + long end = System.currentTimeMillis(); + System.out.println("Time was " + (end - start) + "ms"); + fileIn.close(); + fileOut.close(); + System.out.println("Done!"); + } catch (IOException e) { + System.out.println(e.getMessage()); + } catch (OpusException e) { + System.out.println(e.getMessage()); + } + } + + /// + /// Converts interleaved byte samples (such as what you get from a capture device) + /// into linear short samples (that are much easier to work with) + /// + /// + /// + public static short[] BytesToShorts(byte[] input) { + return BytesToShorts(input, 0, input.length); + } + + /// + /// Converts interleaved byte samples (such as what you get from a capture device) + /// into linear short samples (that are much easier to work with) + /// + /// + /// + public static short[] BytesToShorts(byte[] input, int offset, int length) { + short[] processedValues = new short[length / 2]; + for (int c = 0; c < processedValues.length; c++) { + short a = (short) (((int) input[(c * 2) + offset]) & 0xFF); + short b = (short) (((int) input[(c * 2) + 1 + offset]) << 8); + processedValues[c] = (short) (a | b); + } + + return processedValues; + } + + /// + /// Converts linear short samples into interleaved byte samples, for writing to a file, waveout device, etc. + /// + /// + /// + public static byte[] ShortsToBytes(short[] input) { + return ShortsToBytes(input, 0, input.length); + } + + /// + /// Converts linear short samples into interleaved byte samples, for writing to a file, waveout device, etc. + /// + /// + /// + public static byte[] ShortsToBytes(short[] input, int offset, int length) { + byte[] processedValues = new byte[length * 2]; + for (int c = 0; c < length; c++) { + processedValues[c * 2] = (byte) (input[c + offset] & 0xFF); + processedValues[c * 2 + 1] = (byte) ((input[c + offset] >> 8) & 0xFF); + } + + return processedValues; + } +}