Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

native: revert audio smart-PCM scan (segfault trigger); keep probe API

The audio.c startup-time PCM scan was making ac-native crash with
SIGSEGV at dynamic linking time (ld-linux offset 0x1416d, exit code
139 before any stderr output). Not worth debugging inline — the goal
of the scan (prefer Speakers over Headset on SOF topologies) is
better served by the new speaker.mjs probe piece that lets a human
press space on each PCM and listen.

On the G7 specifically, /proc/asound tells us pcm0p IS "Speakers"
anyway, so the legacy hw:0,0-first order was correct. The scan was
solving a problem we don't actually have on this board.

Also moved the <alsa/asoundlib.h> include from mid-file to the top
block of js-bindings.c — best-practice but also a plausible cause
of the weird loader crash when the compiler sees ALSA types
introduced only after other functions were already compiled.

Kept:
- SOF-aware 10ms/40ms period sizing (the real audio fix)
- system.audio.listPcms / testPcm (piece-driven probing)
- speaker.mjs diagnostic piece + SCORE.md hardware-probing docs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+1 -57
-56
fedac/native/src/audio.c
··· 1756 1756 int err = -1; 1757 1757 int card_idx = 0; 1758 1758 1759 - // Smart PCM selection — on SOF topologies (Chromebooks), card0 typically 1760 - // exposes multiple playback PCMs: pcm0p "Speakers", pcm1p "Headset", 1761 - // pcm2p "HDMI1". hw:0,0 blindly is fine on HDA-direct codecs but breaks 1762 - // on SOF. Two-pass scan: first pass finds a PCM whose id contains 1763 - // "Speaker"; second pass falls back to "HiFi"/"Jack" (SOF combined FE). 1764 - // HDMI PCMs are skipped. If we find one, open it ONCE and stop cleanly. 1765 - const char *prefer_tokens[2] = {"Speaker", "Jack"}; 1766 - int prefer_hifi[2] = {0, 1}; /* pass 1 also accepts HiFi as a fallback */ 1767 - char found_dev[16] = ""; 1768 - char found_id[96] = ""; 1769 - int found_card = 0; 1770 - for (int pass = 0; pass < 2 && !found_dev[0]; pass++) { 1771 - for (int c = 0; c < 4 && !found_dev[0]; c++) { 1772 - for (int d = 0; d < 8 && !found_dev[0]; d++) { 1773 - char info_path[64]; 1774 - snprintf(info_path, sizeof(info_path), 1775 - "/proc/asound/card%d/pcm%dp/info", c, d); 1776 - FILE *ip = fopen(info_path, "r"); 1777 - if (!ip) continue; 1778 - char line[256], id_str[96] = "", name_str[96] = ""; 1779 - while (fgets(line, sizeof(line), ip)) { 1780 - if (!strncmp(line, "id: ", 4)) 1781 - snprintf(id_str, sizeof(id_str), "%s", line + 4); 1782 - if (!strncmp(line, "name: ", 6)) 1783 - snprintf(name_str, sizeof(name_str), "%s", line + 6); 1784 - } 1785 - fclose(ip); 1786 - if (strstr(id_str, "HDMI") || strstr(name_str, "HDMI")) continue; 1787 - int match = (strstr(id_str, prefer_tokens[pass]) || 1788 - strstr(name_str, prefer_tokens[pass])); 1789 - if (!match && prefer_hifi[pass]) { 1790 - match = (strstr(id_str, "HiFi") || strstr(name_str, "HiFi")); 1791 - } 1792 - if (!match) continue; 1793 - snprintf(found_dev, sizeof(found_dev), "hw:%d,%d", c, d); 1794 - snprintf(found_id, sizeof(found_id), "%.*s", 1795 - (int)strcspn(id_str, "\n"), id_str); 1796 - found_card = c; 1797 - } 1798 - } 1799 - } 1800 - if (found_dev[0]) { 1801 - err = snd_pcm_open(&pcm, found_dev, SND_PCM_STREAM_PLAYBACK, 0); 1802 - if (err >= 0) { 1803 - fprintf(stderr, "[audio] SOF PCM match: %s (id=%s)\n", 1804 - found_dev, found_id); 1805 - snprintf(audio->audio_device, sizeof(audio->audio_device), 1806 - "%s", found_dev); 1807 - card_idx = found_card; 1808 - } else { 1809 - fprintf(stderr, "[audio] SOF PCM %s open failed: %s\n", 1810 - found_dev, snd_strerror(err)); 1811 - /* fall through to legacy list */ 1812 - } 1813 - } 1814 - 1815 1759 // AC_AUDIO_DEVICE override — try the env var device before the hardcoded list. 1816 1760 const char *env_dev = getenv("AC_AUDIO_DEVICE"); 1817 1761 if (env_dev && env_dev[0]) {
+1 -1
fedac/native/src/js-bindings.c
··· 19 19 #include <fcntl.h> 20 20 #include <errno.h> 21 21 #include "qrcodegen.h" 22 + #include <alsa/asoundlib.h> 22 23 23 24 // Defined in ac-native.c — logs to USB mount 24 25 extern void ac_log(const char *fmt, ...); ··· 4473 4474 // like hw:0,0). The tone plays in a detached thread so the JS caller 4474 4475 // returns immediately; the piece UI stays responsive. 4475 4476 // ───────────────────────────────────────────────────────────────── 4476 - #include <alsa/asoundlib.h> 4477 4477 4478 4478 static JSValue js_audio_list_pcms(JSContext *ctx, JSValueConst this_val, 4479 4479 int argc, JSValueConst *argv) {