|
|
@ -43,8 +43,8 @@ class OpusAudioManager { |
|
|
const val CHANNEL_RIGHT: Byte = 1 |
|
|
const val CHANNEL_RIGHT: Byte = 1 |
|
|
|
|
|
|
|
|
// 下行合包:左右各自累积 BUNDLE_FRAME_COUNT 帧 opus 合并为 1 包后才下发,降低 BLE 发送频率 |
|
|
// 下行合包:左右各自累积 BUNDLE_FRAME_COUNT 帧 opus 合并为 1 包后才下发,降低 BLE 发送频率 |
|
|
private const val BUNDLE_FRAME_COUNT = 5 |
|
|
private const val BUNDLE_FRAME_COUNT = 4 |
|
|
// 合包头部:bytes 0-3 序号(大端 uint32),byte 4 声道标识(0=左/1=右) |
|
|
// 合包头部:bytes 0-3 序号(小端 uint32),byte 4 声道标识(0=左/1=右) |
|
|
private const val BUNDLE_HEADER_SIZE = 5 |
|
|
private const val BUNDLE_HEADER_SIZE = 5 |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -328,7 +328,13 @@ class OpusAudioManager { |
|
|
audioDataBuffer.clear() |
|
|
audioDataBuffer.clear() |
|
|
Log.d(TAG, "已清理音频数据缓存") |
|
|
Log.d(TAG, "已清理音频数据缓存") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重置合包发送序号 |
|
|
|
|
|
synchronized(bundleLock) { |
|
|
|
|
|
leftBundleSeq = 0 |
|
|
|
|
|
rightBundleSeq = 0 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Log.i(TAG, "已停止Opus数据流解码") |
|
|
Log.i(TAG, "已停止Opus数据流解码") |
|
|
callback?.onDecodeStreamStateChanged(false) |
|
|
callback?.onDecodeStreamStateChanged(false) |
|
|
return true |
|
|
return true |
|
|
@ -428,7 +434,7 @@ class OpusAudioManager { |
|
|
|
|
|
|
|
|
// ====================================================================================================== |
|
|
// ====================================================================================================== |
|
|
// 双声道独立编码方法(左右声道各用独立 OpusManager,互不污染预测状态) |
|
|
// 双声道独立编码方法(左右声道各用独立 OpusManager,互不污染预测状态) |
|
|
// 输出格式:每包 = [4B 序号(大端 uint32)] + [1B 声道(0=左/1=右)] + [N × opus 帧] |
|
|
// 输出格式:每包 = [4B 序号(小端 uint32)] + [1B 声道(0=左/1=右)] + [N × opus 帧] |
|
|
// 左右各自累积 BUNDLE_FRAME_COUNT 帧后打包一次,通过 onAudioDataEncoded 下发 |
|
|
// 左右各自累积 BUNDLE_FRAME_COUNT 帧后打包一次,通过 onAudioDataEncoded 下发 |
|
|
// ====================================================================================================== |
|
|
// ====================================================================================================== |
|
|
|
|
|
|
|
|
@ -513,6 +519,8 @@ class OpusAudioManager { |
|
|
synchronized(bundleLock) { |
|
|
synchronized(bundleLock) { |
|
|
leftBundleFrames.clear() |
|
|
leftBundleFrames.clear() |
|
|
rightBundleFrames.clear() |
|
|
rightBundleFrames.clear() |
|
|
|
|
|
leftBundleSeq = 0 |
|
|
|
|
|
rightBundleSeq = 0 |
|
|
} |
|
|
} |
|
|
closePcmWavWriters() |
|
|
closePcmWavWriters() |
|
|
callback?.onEncodeStreamStateChanged(false) |
|
|
callback?.onEncodeStreamStateChanged(false) |
|
|
@ -553,7 +561,7 @@ class OpusAudioManager { |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 单帧入合包缓冲;左右各自累满 BUNDLE_FRAME_COUNT 帧后整包通过回调下发 |
|
|
* 单帧入合包缓冲;左右各自累满 BUNDLE_FRAME_COUNT 帧后整包通过回调下发 |
|
|
* 输出包布局:[seq(4B 大端 uint32)] + [channel(1B)] + [N 帧 opus 顺次拼接] |
|
|
* 输出包布局:[seq(4B 小端 uint32)] + [channel(1B)] + [N 帧 opus 顺次拼接] |
|
|
*/ |
|
|
*/ |
|
|
private fun emitChannelFrame(channelPrefix: Byte, opusFrame: ByteArray) { |
|
|
private fun emitChannelFrame(channelPrefix: Byte, opusFrame: ByteArray) { |
|
|
val packet: ByteArray? = synchronized(bundleLock) { |
|
|
val packet: ByteArray? = synchronized(bundleLock) { |
|
|
@ -589,10 +597,11 @@ class OpusAudioManager { |
|
|
var payloadSize = 0 |
|
|
var payloadSize = 0 |
|
|
for (f in frames) payloadSize += f.size |
|
|
for (f in frames) payloadSize += f.size |
|
|
val packet = ByteArray(BUNDLE_HEADER_SIZE + payloadSize) |
|
|
val packet = ByteArray(BUNDLE_HEADER_SIZE + payloadSize) |
|
|
packet[0] = (seq ushr 24 and 0xFF).toByte() |
|
|
// 序号小端序:低字节在前 |
|
|
packet[1] = (seq ushr 16 and 0xFF).toByte() |
|
|
packet[0] = (seq and 0xFF).toByte() |
|
|
packet[2] = (seq ushr 8 and 0xFF).toByte() |
|
|
packet[1] = (seq ushr 8 and 0xFF).toByte() |
|
|
packet[3] = (seq and 0xFF).toByte() |
|
|
packet[2] = (seq ushr 16 and 0xFF).toByte() |
|
|
|
|
|
packet[3] = (seq ushr 24 and 0xFF).toByte() |
|
|
packet[4] = channel |
|
|
packet[4] = channel |
|
|
var offset = BUNDLE_HEADER_SIZE |
|
|
var offset = BUNDLE_HEADER_SIZE |
|
|
for (f in frames) { |
|
|
for (f in frames) { |
|
|
|