代码格式整理

This commit is contained in:
loliball 2024-09-01 00:22:21 +08:00
parent 25805cd556
commit 33d1fb0006
4 changed files with 66 additions and 14 deletions

View File

@ -56,4 +56,20 @@ object AudioConvert {
output[i] = shortSample / 32768.0f
}
}
fun bytes2shorts(input: ByteArray, output: ShortArray) {
for (c in output.indices) {
val low = input[(c * 2)].toInt() and 0xFF
val high = input[(c * 2) + 1].toInt() shl 8
output[c] = (low or high).toShort()
}
}
fun shorts2bytes(input: ShortArray, output: ByteArray) {
for (c in input.indices) {
output[c * 2] = (input[c].toInt() and 0xFF).toByte()
output[c * 2 + 1] = ((input[c].toInt() shr 8) and 0xFF).toByte()
}
}
}

View File

@ -4,6 +4,7 @@ import io.github.jaredmdobson.concentus.OpusEncoder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
@ -41,10 +42,9 @@ class Client {
it.complexity = OPUS_COMPLEXITY
}
val scope = CoroutineScope(Dispatchers.IO)
fun mainClient() {
val socket = Socket()
val scope = CoroutineScope(Dispatchers.IO)
val t = measureTimeMillis {
socket.connect(InetSocketAddress(SERVER_HOST, SERVER_PORT))
@ -54,7 +54,7 @@ class Client {
val out = ObjectOutputStream(socket.getOutputStream())
val inp = ObjectInputStream(socket.getInputStream())
scope.launch {
val recordJob = scope.launch {
while (true) {
targetDataLine.read(bufferOut, 0, bufferOut.size)
try {
@ -67,7 +67,7 @@ class Client {
}
}
scope.launch {
val playJob = scope.launch {
while (true) {
try {
// if (`in`!!.available() > bufferIn.size * 2) {
@ -84,5 +84,10 @@ class Client {
}
}
}
runBlocking {
recordJob.join()
playJob.join()
}
}
}

View File

@ -1,5 +1,8 @@
import io.github.jaredmdobson.concentus.*
import kotlinx.coroutines.*
import java.util.concurrent.atomic.AtomicInteger
import javax.print.Doc
import kotlin.concurrent.fixedRateTimer
/**
* Created by LoliBall on 2024/8/31 5:26.
@ -9,7 +12,8 @@ import kotlinx.coroutines.*
//val SERVER_HOST = "zedo.top"
val SERVER_HOST = "127.0.0.1"
val SERVER_PORT = 7860
val ECHO_CANCELLATION = true // 回声消除
val ECHO_CANCELLATION = false // 回声消除
val RAW_PCM_PASS = true // 不进行opus压缩pcm直传
// 2.5, 5, 10, 20, 40, 60 ms
// 120, 240, 480, 960, 1920, 2880
@ -24,27 +28,53 @@ val OPUS_COMPLEXITY = 10 // 0: 快,质量差 10: 慢,质量好
val OPUS_SIGNAL_TYPE = OpusSignal.OPUS_SIGNAL_VOICE
val OPUS_MODE = OpusMode.MODE_HYBRID
fun main() = runBlocking {
CoroutineScope(Dispatchers.IO).launch {
// 下面是统计用的
val compressRateOpus = AtomicInteger()
val compressRatePcm = AtomicInteger()
fun main(args: Array<String>) {
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
Server.main(emptyArray())
}
delay(1000)
Client.main(emptyArray())
delay(Long.MAX_VALUE)
scope.launch {
delay(1000) // 等服务器起来
Client.main(emptyArray())
}
fixedRateTimer(period = 1000) {
"compress rate: %.2f%%".format(compressRateOpus.get() * 100f / compressRatePcm.get()).loge()
compressRateOpus.set(0)
compressRatePcm.set(0)
}
}
val encodeOpusBuffer = mutableMapOf<OpusEncoder, ByteArray>()
val encodePcmShortBuffer = mutableMapOf<OpusEncoder, ShortArray>()
// 1275是opus单帧包最大值
fun OpusEncoder.encode(pcm: ByteArray): DataPack {
if (RAW_PCM_PASS) {
return DataPack(System.currentTimeMillis(), pcm.copyOf())
}
val opusBuffer = encodeOpusBuffer[this] ?: ByteArray(1275).also { encodeOpusBuffer[this] = it }
val bytesEncoded = encode(pcm, 0, PACKET_SAMPLES, opusBuffer, 0, opusBuffer.size)
"compress rate: %.2f%%".format(bytesEncoded / pcm.size.toFloat() * 100).loge()
val shortBuffer = encodePcmShortBuffer[this] ?: ShortArray(pcm.size / 2).also { encodePcmShortBuffer[this] = it }
AudioConvert.bytes2shorts(pcm, shortBuffer)
val bytesEncoded = encode(shortBuffer, 0, PACKET_SAMPLES, opusBuffer, 0, opusBuffer.size)
compressRatePcm.addAndGet(pcm.size)
compressRateOpus.addAndGet(bytesEncoded)
return DataPack(System.currentTimeMillis(), opusBuffer.sliceArray(0..<bytesEncoded))
}
val decodePcmShortBuffer = mutableMapOf<OpusDecoder, ShortArray>()
fun OpusDecoder.decode(pack: DataPack, pcm: ByteArray) {
decode(pack.opus, 0, pack.opus.size, pcm, 0, PACKET_SAMPLES, false)
if (RAW_PCM_PASS) {
pack.opus.copyInto(pcm)
return
}
val shortBuffer = decodePcmShortBuffer[this] ?: ShortArray(pcm.size / 2).also { decodePcmShortBuffer[this] = it }
decode(pack.opus, 0, pack.opus.size, shortBuffer, 0, PACKET_SAMPLES, false)
AudioConvert.shorts2bytes(shortBuffer, pcm)
}
fun <T> T.loge() = also { println(this) }

View File

@ -23,7 +23,8 @@ object Server {
fun mainServer() {
CoroutineScope(Dispatchers.IO).launch {
val scope = CoroutineScope(Dispatchers.IO)
scope.launch {
while (true) {
for (client in clientAudios) {
if (!client.isConnected) {