@glassly/engine 0.3.3-dev.619 → 0.3.3-dev.620

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.
@@ -95,6 +95,7 @@ function projectInfo() {
95
95
  rightMac: s.rightMacAddress,
96
96
  sceneCanvasWidth: s.sceneCanvasWidth,
97
97
  sceneCanvasHeight: s.sceneCanvasHeight,
98
+ volumeGate: s.volumeGate === true,
98
99
  // Copy: the snapshot must not hand callers a mutable reference into the store.
99
100
  wifi: {...s.wifi},
100
101
  }
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
12
12
  export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
13
13
  "schemaVersion": 1,
14
14
  "familyBaseVersion": "0.3.3",
15
- "releaseIdentity": "0.3.3-dev.619",
16
- "releaseSetId": "glassly-0.3.3-dev.619",
17
- "sourceCommit": "ac03782d758bf8129a1ff6f0457519ec3c59800c",
15
+ "releaseIdentity": "0.3.3-dev.620",
16
+ "releaseSetId": "glassly-0.3.3-dev.620",
17
+ "sourceCommit": "b9f332e71049b64f7cba7d038bf41d0e11f47159",
18
18
  "otaManifestUrl": null,
19
19
  "otaManifestSha256": null
20
20
  })
package/src/index.ts CHANGED
@@ -45,6 +45,7 @@ export type {
45
45
  // imperative access goes through engine.settings.
46
46
  export {SETTINGS, useSetting, AI_DATA_CONSENT_VERSION} from "./stores/settings"
47
47
  export {isCfwFirmwareVersion, isCustomDashboardEligible} from "./services/pages/pageEligibility"
48
+ export {getEffectiveCapabilities} from "./services/effectiveCapabilities"
48
49
 
49
50
  // AI tier registry: the curated per-tier model dropdown options and helpers
50
51
  // the Settings > AI Models screen renders. Resolution itself runs inside
@@ -36,17 +36,24 @@ function forceNativeNavigationOnCfw(): boolean {
36
36
  return useSettingsStore.getState().getSetting(SETTINGS.cfw_native_navigation.key) === true
37
37
  }
38
38
 
39
+ /** The connected firmware gates microphone streaming on volume (G2 Glassly CFW revision 40+). */
40
+ export function runtimeVolumeGate(): boolean {
41
+ return useGlassesStore.getState().volumeGate === true
42
+ }
43
+
39
44
  export function getEffectiveCapabilities(model: DeviceTypes): Capabilities {
40
45
  const base = getModelCapabilities(model)
41
- // Only models with a Glassly CFW publish a canvas; never let a stale value
42
- // reshape another model.
46
+ // Only models with a Glassly CFW publish a canvas or a volume gate; never
47
+ // let a stale value reshape another model.
43
48
  const canvas = base.hasCustomFirmware ? runtimeSceneCanvas() : null
44
- if (!base.display || !canvas) return base
49
+ const volumeGate = base.hasCustomFirmware && base.hasMicrophone && runtimeVolumeGate()
50
+ if (!canvas) return volumeGate ? withVolumeGate(base) : base
51
+ if (!base.display) return volumeGate ? withVolumeGate(base) : base
45
52
  // Glassly CFW supports the complete vector contract, including SVG and rotation.
46
53
  // Upstream g2flash publishes a raster canvas with sceneVector=false.
47
54
  const vector = useGlassesStore.getState().sceneVector === true
48
55
  return {
49
- ...base,
56
+ ...(volumeGate ? withVolumeGate(base) : base),
50
57
  hasNativeNavigation: resolveNativeNavigation(base.hasNativeNavigation, true, forceNativeNavigationOnCfw()),
51
58
  display: {
52
59
  ...base.display,
@@ -67,3 +74,7 @@ export function getEffectiveCapabilities(model: DeviceTypes): Capabilities {
67
74
  },
68
75
  }
69
76
  }
77
+
78
+ function withVolumeGate(base: Capabilities): Capabilities {
79
+ return {...base, microphone: {...(base.microphone ?? {}), volumeGate: true}}
80
+ }
@@ -145,6 +145,7 @@ const initialState: GlassesStore = {
145
145
  sceneCanvasHeight: 0,
146
146
  sceneVector: false,
147
147
  sceneSettle: false,
148
+ volumeGate: false,
148
149
  // wifi info
149
150
  wifi: {state: "disconnected"},
150
151
  wifiStatusKnown: false,
@@ -611,6 +611,40 @@ export const SETTINGS: Record<string, Setting> = {
611
611
  saveOnServer: true,
612
612
  persist: true,
613
613
  },
614
+ // G2 Glassly CFW microphone volume gate (revision 40+): the temples stop
615
+ // streaming audio while nothing reaches the threshold. Off until the user
616
+ // turns it on; shown only when the connected firmware reports the capability.
617
+ volume_gate_enabled: {
618
+ key: "volume_gate_enabled",
619
+ defaultValue: () => false,
620
+ writable: true,
621
+ saveOnServer: true,
622
+ persist: true,
623
+ },
624
+ // dBFS RMS a 50 ms chunk must reach to count as sound.
625
+ volume_gate_threshold_db: {
626
+ key: "volume_gate_threshold_db",
627
+ defaultValue: () => -45,
628
+ writable: true,
629
+ saveOnServer: true,
630
+ persist: true,
631
+ },
632
+ // Quiet time before the gate closes.
633
+ volume_gate_hold_ms: {
634
+ key: "volume_gate_hold_ms",
635
+ defaultValue: () => 3000,
636
+ writable: true,
637
+ saveOnServer: true,
638
+ persist: true,
639
+ },
640
+ // Minimum time the gate stays open once sound opens it.
641
+ volume_gate_min_open_ms: {
642
+ key: "volume_gate_min_open_ms",
643
+ defaultValue: () => 2000,
644
+ writable: true,
645
+ saveOnServer: true,
646
+ persist: true,
647
+ },
614
648
  always_on_status_bar: {
615
649
  key: "always_on_status_bar",
616
650
  defaultValue: () => false,
@@ -1108,6 +1142,10 @@ export const BLUETOOTH_SETTING_KEYS: string[] = [
1108
1142
  SETTINGS.power_saving_mode.key,
1109
1143
  SETTINGS.voice_activity_detection_enabled.key,
1110
1144
  SETTINGS.loudness_gate_enabled.key,
1145
+ SETTINGS.volume_gate_enabled.key,
1146
+ SETTINGS.volume_gate_threshold_db.key,
1147
+ SETTINGS.volume_gate_hold_ms.key,
1148
+ SETTINGS.volume_gate_min_open_ms.key,
1111
1149
  SETTINGS.lc3_frame_size.key,
1112
1150
  SETTINGS.preferred_mic.key,
1113
1151
  SETTINGS.screen_disabled.key,
@@ -95,6 +95,10 @@ export const ALL_DISPLAY_SHAPES: DisplayShape[] = ["rect", "circle", "arc", "pie
95
95
  export interface MicrophoneCapabilities {
96
96
  count?: number
97
97
  hasVAD?: boolean // Voice Activity Detection
98
+ // The connected firmware can stop streaming audio below a volume floor
99
+ // (G2 Glassly CFW revision 40+). Never set on a model profile: it is
100
+ // reported at runtime and layered on by getEffectiveCapabilities.
101
+ volumeGate?: boolean
98
102
  }
99
103
 
100
104
  /**