Commit 9a27099e authored by martin hou's avatar martin hou

fix: 适配16k采样率的实时音频流

parent dbc24bdd
......@@ -491,13 +491,14 @@ export function Home() {
const totalFrames = Math.floor((u8.length - 8) / 4);
if (totalFrames <= 0) return [0, 0, new Uint8Array(0)];
// 48k -> 16k,降采样因子为3
const downFactor = 3;
const outFrames = Math.floor((totalFrames + downFactor - 1) / downFactor) * 2; // 向上取整
const downFactor = 1;
const outFrames = totalFrames;
let sumL = 0;
let sumR = 0;
const mono8 = new Uint8Array(outFrames + 8);
let j = 0, k = 0;
for (let i = 8; i + 3 < u8.length; i += 4, j++)
const mono8 = new Uint8Array(outFrames * 2 + 8);
console.log('sampling', outFrames, u8.byteLength);
let k = 0;
for (let i = 8; i + 3 < u8.length; i += 4)
{
const a = u8[i + 0] & 0xff;
const b = u8[i + 1] & 0xff;
......@@ -513,19 +514,16 @@ export function Home() {
const nr = r / 32768;
sumL += nl * nl;
sumR += nr * nr;
// 双声道合成为单声道(16-bit),再压缩为 Int8
// C = A + B - (A * B / 32767)
if (j % downFactor == 0)
{
let m = l + r - Math.floor((l * r) / 32767);
// 双声道合成为单声道;双静音直接归零避免底噪,其他情况用平均叠加
const nearSilent = Math.abs(l) < 4 && Math.abs(r) < 4;
let m = nearSilent ? 0 : (l + r) / 2;
if (m > 32767) m = 32767;
else if (m < -32768) m = -32768;
let H = (m >> 8) & 0xff;
let L = m & 0xff;
mono8[8 + k++] = (L << 8);
const H = (m >> 8) & 0xff;
const L = m & 0xff;
mono8[8 + k++] = L;
mono8[8 + k++] = H;
}
}
const leftRms = Math.sqrt(sumL / totalFrames);
const rightRms = Math.sqrt(sumR / totalFrames);
// 返回实际长度的视图,避免尾部未填充元素
......@@ -533,6 +531,7 @@ export function Home() {
}
const blocksRef = useRef<Uint8Array[]>([]);
const scheduleLiveTick = async () => {
let jensen = getJensen();
if (jensen == null) return;
......@@ -569,10 +568,12 @@ export function Home() {
liveTimeoutRef.current = window.setTimeout(scheduleLiveTick, 100);
// 开启发送音频定时器
/*
if (sendTimeoutRef.current !== null) {
window.clearTimeout(sendTimeoutRef.current);
}
sendTimeoutRef.current = window.setTimeout(sendLiveAudio, 100);
*/
}
function stringToUuidBytes(str: string): Uint8Array {
......@@ -620,8 +621,8 @@ export function Home() {
// 创建一个websocket实例
const wsRef = useRef<WebSocket | null>(null);
const startLiveSession = async () => {
const token = 'kL5NmbPEGOptIGbt8jtR3pjXVHT9p774n7N4oQAARb0ctUMnq4bABgBPZ7QjYSUi';
if (new Date().getTime() > 0) return startSession();
const token = 'O9UkcTQg1l9HbKocNuNVplRhI3q7JdTRiQAP5j3zjSFNQ2yRd3crH0HrDfRDP7TH';
let url = 'wss://live.test.hidock.com/ws/realtime?accesstoken=' + token + '&mode=room&language=cmn&';
// wss://live.test.hidock.com/ws/realtime?accesstoken=&mode=room&language=cmn
wsRef.current = new WebSocket(url);
......@@ -657,11 +658,11 @@ export function Home() {
}
if (data.type == 'partial')
{
console.log('live', data.text);
console.log('live-text', data.text);
}
if (data.type == 'final')
{
console.log('live', data.text);
console.log('live-text', data.text);
}
}
wsRef.current.onerror = (event) => {
......@@ -688,14 +689,13 @@ export function Home() {
window.clearTimeout(liveTimeoutRef.current);
liveTimeoutRef.current = null;
}
console.log('live stopped');
/*
const totalSamples = blocksRef.current.reduce((sum, arr) => sum + arr.length, 0);
Logger.info('jensen', 'live', 'live stopped');
const totalSamples = blocksRef.current.reduce((sum, arr) => sum + arr.length - 8, 0);
const monoAll = new Uint8Array(totalSamples);
let offsetMono = 0;
for (const arr of blocksRef.current) {
monoAll.set(arr, offsetMono);
offsetMono += arr.length;
monoAll.set(arr.slice(8), offsetMono);
offsetMono += arr.length - 8;
}
let blob = new Blob([monoAll.buffer], { type: 'audio/pcm' });
let url = URL.createObjectURL(blob);
......@@ -704,7 +704,6 @@ export function Home() {
a.download = 'live.pcm';
a.click();
URL.revokeObjectURL(url);
*/
}
return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment