opencharm 0.8.7 → 0.8.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.mjs +2 -2
- package/package.json +1 -1
- package/sim/charm_sim.wasm +0 -0
- package/sim/sim.js +20 -2
package/dist/main.mjs
CHANGED
|
@@ -997,7 +997,7 @@ function sendAdmin(socketPath, request) {
|
|
|
997
997
|
}
|
|
998
998
|
//#endregion
|
|
999
999
|
//#region package.json
|
|
1000
|
-
var version = "0.8.
|
|
1000
|
+
var version = "0.8.8";
|
|
1001
1001
|
function channelToCube(value) {
|
|
1002
1002
|
if (value < 48) return 0;
|
|
1003
1003
|
if (value < 115) return 1;
|
|
@@ -5056,7 +5056,7 @@ function formatIdentity(unit, version, commit) {
|
|
|
5056
5056
|
let cached;
|
|
5057
5057
|
function identity() {
|
|
5058
5058
|
if (cached) return cached;
|
|
5059
|
-
const commit = "
|
|
5059
|
+
const commit = "89e832a";
|
|
5060
5060
|
cached = {
|
|
5061
5061
|
version: `cli@${version}`,
|
|
5062
5062
|
commit,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencharm",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8",
|
|
4
4
|
"description": "An open-source body for the AI agent you already run: a face, a voice, one key. Claude Code, Codex, Gemini CLI, Hermes, OpenClaw or any ACP or OpenAI-compatible agent; on a small board, your Mac's notch or the browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/sim/charm_sim.wasm
CHANGED
|
Binary file
|
package/sim/sim.js
CHANGED
|
@@ -51,6 +51,7 @@ const trace = {
|
|
|
51
51
|
connected: false,
|
|
52
52
|
micReady: false, // the microphone is open right now (only while the key is held)
|
|
53
53
|
micOpens: 0, // how many times it was opened
|
|
54
|
+
micLatencyMs: null, // key-down to the first mic frame the core took, last hold (includes a 60 ms frame)
|
|
54
55
|
};
|
|
55
56
|
window.__charm = trace;
|
|
56
57
|
|
|
@@ -58,6 +59,8 @@ let ws;
|
|
|
58
59
|
let wifiOn = true;
|
|
59
60
|
let micOn = false;
|
|
60
61
|
let keyHeld = false;
|
|
62
|
+
let keyDownAt = 0;
|
|
63
|
+
let firstFrame = false;
|
|
61
64
|
let mic; // {stream, ctx} while the key is held; the microphone is closed otherwise
|
|
62
65
|
let playCtx;
|
|
63
66
|
let playAt = 0;
|
|
@@ -259,8 +262,12 @@ async function openMic() {
|
|
|
259
262
|
opening.stream = await navigator.mediaDevices.getUserMedia({
|
|
260
263
|
audio: {
|
|
261
264
|
channelCount: 1,
|
|
262
|
-
|
|
263
|
-
|
|
265
|
+
// No voice processing: the charm never plays while the mic runs (a hold stops its speech
|
|
266
|
+
// first), and on macOS it makes WebKit open the mic through Apple's voice-processing unit,
|
|
267
|
+
// which ducks other sound and is expected to start slower, cutting a first word.
|
|
268
|
+
echoCancellation: false,
|
|
269
|
+
noiseSuppression: false,
|
|
270
|
+
autoGainControl: false,
|
|
264
271
|
},
|
|
265
272
|
});
|
|
266
273
|
await opening.ctx.audioWorklet.addModule("mic-worklet.js");
|
|
@@ -272,6 +279,13 @@ async function openMic() {
|
|
|
272
279
|
const ptr = M._malloc(bytes.length);
|
|
273
280
|
M.HEAPU8.set(bytes, ptr);
|
|
274
281
|
M._sim_mic_pcm(ptr, data.length);
|
|
282
|
+
if (!firstFrame) {
|
|
283
|
+
firstFrame = true;
|
|
284
|
+
trace.micLatencyMs = Math.round(performance.now() - keyDownAt);
|
|
285
|
+
console.debug(
|
|
286
|
+
`OpenCharm emulator: first mic frame ${trace.micLatencyMs} ms after key-down`
|
|
287
|
+
);
|
|
288
|
+
}
|
|
275
289
|
M._free(ptr);
|
|
276
290
|
};
|
|
277
291
|
if (fakeMic) {
|
|
@@ -309,6 +323,10 @@ window.charmKey = (down) => key(down);
|
|
|
309
323
|
function key(down) {
|
|
310
324
|
startPlayback();
|
|
311
325
|
keyHeld = down;
|
|
326
|
+
if (down) {
|
|
327
|
+
keyDownAt = performance.now();
|
|
328
|
+
firstFrame = false;
|
|
329
|
+
}
|
|
312
330
|
if (down) void openMic();
|
|
313
331
|
else closeMic();
|
|
314
332
|
keyEl.classList.toggle("down", down);
|