런타임 계약과 학습자 흐름 보강
This commit is contained in:
parent
f456b8997a
commit
206018b088
56 changed files with 4306 additions and 1008 deletions
56
apps/web/public/worklets/voice-capture-worklet.js
Normal file
56
apps/web/public/worklets/voice-capture-worklet.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
class VoiceCaptureProcessor extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super();
|
||||
this.pending = [];
|
||||
this.pendingLength = 0;
|
||||
this.flushSamples = Math.max(1024, Math.floor(sampleRate * 0.25));
|
||||
this.port.onmessage = (event) => {
|
||||
if (event.data && event.data.type === "flush") {
|
||||
this.flush();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
process(inputs) {
|
||||
const input = inputs[0];
|
||||
const channel = input && input[0];
|
||||
if (!channel || channel.length === 0) return true;
|
||||
|
||||
const pcm = new Int16Array(channel.length);
|
||||
for (let i = 0; i < channel.length; i += 1) {
|
||||
const sample = Math.max(-1, Math.min(1, channel[i]));
|
||||
pcm[i] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
|
||||
}
|
||||
|
||||
this.pending.push(pcm);
|
||||
this.pendingLength += pcm.length;
|
||||
if (this.pendingLength >= this.flushSamples) {
|
||||
this.flush();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
flush() {
|
||||
if (this.pendingLength <= 0) return;
|
||||
const merged = new Int16Array(this.pendingLength);
|
||||
let offset = 0;
|
||||
for (const chunk of this.pending) {
|
||||
merged.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
this.pending = [];
|
||||
this.pendingLength = 0;
|
||||
this.port.postMessage(
|
||||
{
|
||||
type: "chunk",
|
||||
sampleRate,
|
||||
channels: 1,
|
||||
sampleWidth: 2,
|
||||
pcm: merged.buffer,
|
||||
},
|
||||
[merged.buffer],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor("voice-capture-processor", VoiceCaptureProcessor);
|
||||
Loading…
Add table
Add a link
Reference in a new issue