From 2bd2c98e7bbb06682407c45a47b6f5c76cc0059c Mon Sep 17 00:00:00 2001 From: zedoCN Date: Sat, 31 Aug 2024 03:19:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=A8=E9=83=A8=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/checkstyle-idea.xml | 16 ++++++ src/AudioConvert.kt | 52 +++++++++-------- src/Client.kt | 99 ++++++++++++++++---------------- src/Server.kt | 117 +++++++++++++++++++------------------- 4 files changed, 151 insertions(+), 133 deletions(-) create mode 100644 .idea/checkstyle-idea.xml diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100644 index 0000000..e5bd10c --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,16 @@ + + + + 10.18.0 + JavaOnly + true + + + \ No newline at end of file diff --git a/src/AudioConvert.kt b/src/AudioConvert.kt index 3dce945..1fbb1f9 100644 --- a/src/AudioConvert.kt +++ b/src/AudioConvert.kt @@ -1,9 +1,18 @@ -import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioFormat +import kotlin.math.max +import kotlin.math.min -public class AudioConvert { - - public static AudioFormat getAudioFormat(int sampleRate, int channels) { - return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, sampleRate, 16, channels, channels * 2, sampleRate, false); +object AudioConvert { + fun getAudioFormat(sampleRate: Int, channels: Int): AudioFormat { + return AudioFormat( + AudioFormat.Encoding.PCM_SIGNED, + sampleRate.toFloat(), + 16, + channels, + channels * 2, + sampleRate.toFloat(), + false + ) } /** @@ -12,21 +21,19 @@ public class AudioConvert { * @param input 输入的 float[] 数据 * @param output 转换后的 byte[] 数据 */ - public static void convertFloatToShortByte(float[] input, byte[] output) { - if (input.length * 2 != output.length) { - throw new IllegalArgumentException("output byte array length must be twice the length of the input float array."); - } + fun convertFloatToShortByte(input: FloatArray, output: ByteArray) { + require(input.size * 2 == output.size) { "output byte array length must be twice the length of the input float array." } - for (int i = 0; i < input.length; i++) { + for (i in input.indices) { // 将 float 值限制在 -1.0 到 1.0 之间 - float sample = Math.min(Math.max(input[i], -1.0f), 1.0f); + val sample = min(max(input[i].toDouble(), -1.0), 1.0).toFloat() // 将 float 值转换为 short - short shortSample = (short) (sample * 32767); + val shortSample = (sample * 32767).toInt().toShort() // 将 short 值转换为两个字节,并存储在 lineBuffer 中 - output[i * 2] = (byte) (shortSample & 0xFF); // 低位字节 - output[i * 2 + 1] = (byte) ((shortSample >> 8) & 0xFF); // 高位字节 + output[i * 2] = (shortSample.toInt() and 0xFF).toByte() // 低位字节 + output[i * 2 + 1] = ((shortSample.toInt() shr 8) and 0xFF).toByte() // 高位字节 } } @@ -36,20 +43,17 @@ public class AudioConvert { * @param input 输入的 byte[] 数据(每两个字节表示一个 short) * @param output 转换后的 float[] 数据 */ - public static void convertShortByteToFloat(byte[] input, float[] output) { - if (input.length != output.length * 2) { - throw new IllegalArgumentException("Input byte array length must be twice the length of the output float array."); - } + fun convertShortByteToFloat(input: ByteArray, output: FloatArray) { + require(input.size == output.size * 2) { "Input byte array length must be twice the length of the output float array." } - for (int i = 0; i < output.length; i++) { + for (i in output.indices) { // 将两个字节转换为 short - int low = input[i * 2] & 0xFF; - int high = input[i * 2 + 1] & 0xFF; - short shortSample = (short) ((high << 8) | low); + val low = input[i * 2].toInt() and 0xFF + val high = input[i * 2 + 1].toInt() and 0xFF + val shortSample = ((high shl 8) or low).toShort() // 将 short 值转换为 float - output[i] = shortSample / 32768.0f; + output[i] = shortSample / 32768.0f } } - } diff --git a/src/Client.kt b/src/Client.kt index 264fd95..a409d46 100644 --- a/src/Client.kt +++ b/src/Client.kt @@ -1,70 +1,71 @@ -import javax.sound.sampled.AudioFormat; -import javax.sound.sampled.AudioSystem; -import javax.sound.sampled.SourceDataLine; -import javax.sound.sampled.TargetDataLine; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.net.Socket +import javax.sound.sampled.AudioFormat +import javax.sound.sampled.AudioSystem +import javax.sound.sampled.SourceDataLine +import javax.sound.sampled.TargetDataLine -public class Client { - public static InputStream in; - public static OutputStream out; - public static SourceDataLine sourceDataLine; - public static TargetDataLine targetDataLine; - public static byte[] bufferOut; - public static byte[] bufferIn; - public static float[] sample; - public static int SAMPLE_RATE = 48000; - public static int CHANNELS = 1; - public static AudioFormat format = AudioConvert.getAudioFormat(SAMPLE_RATE, CHANNELS); - public static Socket socket; +object Client { + var `in`: InputStream? = null + var out: OutputStream? = null + var sourceDataLine: SourceDataLine? = null + var targetDataLine: TargetDataLine? = null + var bufferOut: ByteArray + var bufferIn: ByteArray + var sample: FloatArray + var SAMPLE_RATE: Int = 48000 + var CHANNELS: Int = 1 + var format: AudioFormat = AudioConvert.getAudioFormat(SAMPLE_RATE, CHANNELS) + var socket: Socket? = null - public static void main(String[] args) throws Exception { - socket = new Socket("127.0.0.1", 7860); - in = socket.getInputStream(); - out = socket.getOutputStream(); - sample = new float[Server.BUFFER_SIZE]; - bufferIn = new byte[sample.length * 2]; - bufferOut = new byte[sample.length * 2]; + @Throws(Exception::class) + @JvmStatic + fun main(args: Array) { + socket = Socket("127.0.0.1", 7860) + `in` = socket!!.getInputStream() + out = socket!!.getOutputStream() + sample = FloatArray(Server.BUFFER_SIZE) + bufferIn = ByteArray(sample.size * 2) + bufferOut = ByteArray(sample.size * 2) - targetDataLine = AudioSystem.getTargetDataLine(format); - targetDataLine.open(format, bufferIn.length); - targetDataLine.start(); + targetDataLine = AudioSystem.getTargetDataLine(format) + targetDataLine.open(format, bufferIn.size) + targetDataLine.start() - sourceDataLine = AudioSystem.getSourceDataLine(format); - sourceDataLine.open(format, bufferIn.length); - sourceDataLine.start(); + sourceDataLine = AudioSystem.getSourceDataLine(format) + sourceDataLine.open(format, bufferIn.size) + sourceDataLine.start() - new Thread(() -> { + Thread { while (true) { //Arrays.fill(bufferOut, (byte) 0); - targetDataLine.read(bufferOut, 0, bufferOut.length); + targetDataLine.read(bufferOut, 0, bufferOut.size) try { - out.write(bufferOut, 0, bufferOut.length); - out.flush(); - } catch (Exception e) { - e.printStackTrace(); - System.exit(0); + out.write(bufferOut, 0, bufferOut.size) + out.flush() + } catch (e: Exception) { + e.printStackTrace() + System.exit(0) } } - }).start(); + }.start() - new Thread(() -> { + Thread { while (true) { try { - in.read(bufferIn, 0, bufferIn.length); - sourceDataLine.write(bufferIn, 0, bufferIn.length); - } catch (IOException e) { - e.printStackTrace(); - System.exit(0); + `in`.read(bufferIn, 0, bufferIn.size) + sourceDataLine.write(bufferIn, 0, bufferIn.size) + } catch (e: IOException) { + e.printStackTrace() + System.exit(0) } - } - }).start(); + }.start() /* diff --git a/src/Server.kt b/src/Server.kt index 3bfbe4d..4319099 100644 --- a/src/Server.kt +++ b/src/Server.kt @@ -1,98 +1,95 @@ -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; +import java.io.IOException +import java.io.InputStream +import java.io.OutputStream +import java.net.ServerSocket +import java.net.Socket +import java.util.* +import java.util.concurrent.CopyOnWriteArrayList -public class Server { +object Server { + var clientAudios: MutableList = CopyOnWriteArrayList() + @kotlin.jvm.JvmField + var BUFFER_SIZE: Int = 2048 * Client.CHANNELS + var mixSample: FloatArray = FloatArray(BUFFER_SIZE) + var buffer: ByteArray = ByteArray(BUFFER_SIZE * 2) - public static List clientAudios = new CopyOnWriteArrayList<>(); - public static int BUFFER_SIZE = 2048 * Client.CHANNELS; - public static float[] mixSample = new float[BUFFER_SIZE]; - public static byte[] buffer = new byte[BUFFER_SIZE * 2]; - - public static void main(String[] args) throws Exception { + @kotlin.Throws(Exception::class) + @kotlin.jvm.JvmStatic + fun main(args: Array) { //混音 - new Thread(() -> { + Thread { while (true) { - for (var client : clientAudios) { - if (!client.isConnected()) { - clientAudios.remove(client); - System.out.println("现在是: "+clientAudios); - continue; + for (client in clientAudios) { + if (!client.isConnected) { + clientAudios.remove(client) + println("现在是: " + clientAudios) + continue } - client.read(); + client.read() } - for (var client : clientAudios) { - Arrays.fill(mixSample, 0); - for (var audio : clientAudios) { + for (client in clientAudios) { + Arrays.fill(mixSample, 0f) + for (audio in clientAudios) { //if (audio != client) - audio.mix(mixSample); + audio.mix(mixSample) } - AudioConvert.convertFloatToShortByte(mixSample, buffer); - client.send(buffer); + AudioConvert.convertFloatToShortByte(mixSample, buffer) + client.send(buffer) } //System.out.println("混音"); } - }).start(); + }.start() - ServerSocket sever = new ServerSocket(7860); + val sever = ServerSocket(7860) while (true) { - Socket socket = sever.accept(); - System.out.println("Accepted connection from " + socket.getRemoteSocketAddress()); - clientAudios.add(new ClientAudio(socket)); + val socket = sever.accept() + println("Accepted connection from " + socket.remoteSocketAddress) + clientAudios.add(ClientAudio(socket)) } } - public static class ClientAudio { - Socket socket; - InputStream in; - OutputStream out; - byte[] buffer = new byte[BUFFER_SIZE * 2]; - float[] sample = new float[BUFFER_SIZE]; + class ClientAudio(var socket: Socket) { + var `in`: InputStream? = null + var out: OutputStream? = null + var buffer: ByteArray = ByteArray(BUFFER_SIZE * 2) + var sample: FloatArray = FloatArray(BUFFER_SIZE) - public ClientAudio(Socket socket) { - this.socket = socket; + init { try { - in = socket.getInputStream(); - out = socket.getOutputStream(); - - } catch (IOException e) { - throw new RuntimeException(e); + `in` = socket.getInputStream() + out = socket.getOutputStream() + } catch (e: IOException) { + throw RuntimeException(e) } } - public boolean isConnected() { - return socket.isConnected(); - } + val isConnected: Boolean + get() = socket.isConnected - public void send(byte[] buffer) { + fun send(buffer: ByteArray) { try { - out.write(buffer); - out.flush(); - } catch (IOException e) { + out!!.write(buffer) + out!!.flush() + } catch (e: IOException) { } } - public void read() { + fun read() { try { - in.read(buffer); - AudioConvert.convertShortByteToFloat(buffer, sample); - } catch (IOException e) { + `in`!!.read(buffer) + AudioConvert.convertShortByteToFloat(buffer, sample) + } catch (e: IOException) { //throw new RuntimeException(e); } } - public void mix(float[] sample) { - for (int i = 0; i < sample.length; i++) { - sample[i] += this.sample[i]; + fun mix(sample: FloatArray) { + for (i in sample.indices) { + sample[i] += this.sample[i] } } }