<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://dev1galaxy.org/extern.php?action=feed&amp;tid=7603&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Dev1 Galaxy Forum / Why Zoom Doesn’t Work with Firefox’s ALSA Backend]]></title>
		<link>https://dev1galaxy.org/viewtopic.php?id=7603</link>
		<description><![CDATA[The most recent posts in Why Zoom Doesn’t Work with Firefox’s ALSA Backend.]]></description>
		<lastBuildDate>Mon, 24 Nov 2025 16:45:51 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[Re: Why Zoom Doesn’t Work with Firefox’s ALSA Backend]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=60042#p60042</link>
			<description><![CDATA[<p>You can test it with <strong>LibreWolf</strong> browser.</p><div class="quotebox"><blockquote><div><p>_https://librewolf.net/installation/debian/<br />We have <strong>a repository for Debian-based distributions</strong> (Debian, Ubuntu, Mint, etc.), with which you can easily install and update LibreWolf. To add it to your system and install LibreWolf, run the following commands one by one:</p><div class="codebox"><pre><code>sudo apt update &amp;&amp; sudo apt install extrepo -y</code></pre></div><div class="codebox"><pre><code>sudo extrepo enable librewolf</code></pre></div><div class="codebox"><pre><code>sudo apt update &amp;&amp; sudo apt install librewolf -y</code></pre></div></div></blockquote></div><p><strong>Disable</strong> <span class="bbc">pulse-rust</span> <strong>backend</strong></p><div class="codebox"><pre><code>librewolf about:config</code></pre></div><p>Type into &quot;Search preference name&quot;</p><div class="codebox"><pre><code>media.cubeb.backend</code></pre></div><p>Select &quot;string&quot;<br />Press &quot;+&quot;<br />Type &quot;alsa&quot; then Enter</p><p>As a result, you have a new entry in Firefox&#039;s &quot;hidden preferences&quot;</p><div class="codebox"><pre><code>media.cubeb.backend		alsa</code></pre></div><p>Re-start LibreWolf.</p><p><strong>Zoom Zoom Extension for Browsers → Firefox Add-ons</strong><br />_https://zoom.us/download</p>]]></description>
			<author><![CDATA[dummy@example.com (igorzwx)]]></author>
			<pubDate>Mon, 24 Nov 2025 16:45:51 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=60042#p60042</guid>
		</item>
		<item>
			<title><![CDATA[Re: Why Zoom Doesn’t Work with Firefox’s ALSA Backend]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=59995#p59995</link>
			<description><![CDATA[<p>Hello:</p><div class="quotebox"><cite>igorzwx wrote:</cite><blockquote><div><p>... ALSA as a fallback — a bare-bones option for when PulseAudio isn’t available.<br />... overlooks that ALSA, with its default software mixing, is quite capable.</p></div></blockquote></div><p>Very practical of them.<br />How else will they get people to use Poettering&#039;s <span class="bbc">PulseAudio</span> <em>complication</em>?</p><div class="quotebox"><cite>igorzwx wrote:</cite><blockquote><div><p>... a full rewrite — replacing fiction with fact — is the only sensible path forward.</p></div></blockquote></div><p>I wonder what the odds on that happening are?</p><p>Maybe I&#039;ll call my bookie and ask.&#160; 8^°</p><p>Best,</p><p>A.</p>]]></description>
			<author><![CDATA[dummy@example.com (Altoid)]]></author>
			<pubDate>Sun, 23 Nov 2025 16:03:18 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=59995#p59995</guid>
		</item>
		<item>
			<title><![CDATA[Why Zoom Doesn’t Work with Firefox’s ALSA Backend]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=59994#p59994</link>
			<description><![CDATA[<p>It’s not so much that Firefox <em>can’t</em> handle ALSA, but rather that its cubeb backend takes a somewhat… <em>minimalist</em> approach to device enumeration.</p><p>The issue lies in <span class="bbc">alsa_enumerate_devices()</span>, which, rather than listing actual hardware, returns a single, rather fictional &quot;default&quot; device (cubeb_alsa.c:1408–1456). This isn’t so much discovery as polite suggestion.</p><p><strong>The Present Situation</strong></p><p>Currently, the backend reports a device with:</p><p>- A maximum of 10,000 channels (ambitious, if not grounded in reality),<br />- Zero latency (one can only dream),<br />- And a fixed sample rate of 48,000 Hz (cubeb_alsa.c:1430–1451).</p><p>Unsurprisingly, Zoom’s web client sees “internal speakers” and “internal mic” — but they’re rather like ghosts: visible, yet impossible to engage with (e.g., Zoom’s web client with Mozilla LibreWolf 145.0.1-2, cubeb&#039;s ALSA backend).</p><p><strong>What</strong> <span class="bbc">snd_device_name_hint</span> <strong>Actually Does</strong></p><p>This is ALSA’s proper device discovery function. It returns real devices — hardware, plugins, virtuals — with actual capabilities. It’s what one might reasonably expect to be used.</p><p><strong>Why a Complete Rewrite Is in Order</strong></p><p>To fix this, the cubeb ALSA backend would need to:</p><p>1. Call <span class="bbc">snd_device_name_hint()</span> — a modest step, but one currently overlooked.<br />2. Query real hardware parameters — using standard ALSA calls to learn actual channel counts, rates, and latencies (cubeb_alsa.c:1213–1221).<br />3. Distinguish input, output, and duplex devices — a basic courtesy to the user.<br />4. Expose the actual ALSA topology — including asymmetric setups using <span class="bbc">dmix</span> and <span class="bbc">dsnoop</span>, which many rely on.</p><p><strong>Why This Hasn’t Happened</strong></p><p>The developers appear to have treated ALSA as a fallback — a bare-bones option for when PulseAudio isn’t available. This overlooks that ALSA, with its default software mixing, is quite capable. The current implementation suffices for playing the odd YouTube video, but falters when full-duplex communication — such as a Zoom call — is required.</p><p><strong>For Comparison</strong></p><p>The OSS backend in cubeb <em>does</em> properly enumerate devices by probing <span class="bbc">/dev/sndstat</span> (cubeb_oss.c:344–443). A similar effort for ALSA would be only reasonable.</p><p><strong>In Summary</strong></p><p>The fix amounts to implementing what the standalone Zoom app already does: using ALSA as it’s meant to be used. The current stub is so far from proper enumeration that a full rewrite — replacing fiction with fact — is the only sensible path forward.</p><p><strong>Citations</strong></p><p><strong>File:</strong> src/cubeb_alsa.c (L73-78)</p><div class="codebox"><pre><code>#define CUBEB_STREAM_MAX 16
#define CUBEB_WATCHDOG_MS 10000

#define CUBEB_ALSA_PCM_NAME &quot;default&quot;

#define ALSA_PA_PLUGIN &quot;ALSA &lt;-&gt; PulseAudio PCM I/O Plugin&quot;</code></pre></div><p><strong>File:</strong> src/cubeb_alsa.c (L1213-1221)</p><div class="codebox"><pre><code> 
  r = WRAP(snd_pcm_hw_params_any)(stm-&gt;pcm, hw_params);
  if (r &lt; 0) {
    return CUBEB_ERROR;
  }

  r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels);
  if (r &lt; 0) {
    return CUBEB_ERROR;
  }</code></pre></div><p>&#160; <br /><strong>File:</strong> src/cubeb_alsa.c (L1408-1456)</p><div class="codebox"><pre class="vscroll"><code>static int
alsa_enumerate_devices(cubeb * context, cubeb_device_type type,
                       cubeb_device_collection * collection)
{
  cubeb_device_info * device = NULL;

  if (!context)
    return CUBEB_ERROR;

  uint32_t rate, max_channels;
  int r;

  r = alsa_get_preferred_sample_rate(context, &amp;rate);
  if (r != CUBEB_OK) {
    return CUBEB_ERROR;
  }

  r = alsa_get_max_channel_count(context, &amp;max_channels);
  if (r != CUBEB_OK) {
    return CUBEB_ERROR;
  }

  char const * a_name = &quot;default&quot;;
  device = (cubeb_device_info *)calloc(1, sizeof(cubeb_device_info));
  assert(device);
  if (!device)
    return CUBEB_ERROR;

  device-&gt;device_id = a_name;
  device-&gt;devid = (cubeb_devid)device-&gt;device_id;
  device-&gt;friendly_name = a_name;
  device-&gt;group_id = a_name;
  device-&gt;vendor_name = a_name;
  device-&gt;type = type;
  device-&gt;state = CUBEB_DEVICE_STATE_ENABLED;
  device-&gt;preferred = CUBEB_DEVICE_PREF_ALL;
  device-&gt;format = CUBEB_DEVICE_FMT_S16NE;
  device-&gt;default_format = CUBEB_DEVICE_FMT_S16NE;
  device-&gt;max_channels = max_channels;
  device-&gt;min_rate = rate;
  device-&gt;max_rate = rate;
  device-&gt;default_rate = rate;
  device-&gt;latency_lo = 0;
  device-&gt;latency_hi = 0;

  collection-&gt;device = device;
  collection-&gt;count = 1;

  return CUBEB_OK;</code></pre></div><p><strong>File:</strong> src/cubeb_oss.c (L344-443)</p><div class="codebox"><pre class="vscroll"><code>static int
oss_enumerate_devices(cubeb * context, cubeb_device_type type,
                      cubeb_device_collection * collection)
{
  cubeb_device_info * devinfop = NULL;
  char * line = NULL;
  size_t linecap = 0;
  FILE * sndstatfp = NULL;
  int collection_cnt = 0;
  int is_ud = 0;
  int skipall = 0;

  devinfop = calloc(1, sizeof(cubeb_device_info));
  if (devinfop == NULL)
    goto fail;

  sndstatfp = fopen(&quot;/dev/sndstat&quot;, &quot;r&quot;);
  if (sndstatfp == NULL)
    goto fail;
  while (getline(&amp;line, &amp;linecap, sndstatfp) &gt; 0) {
    const char * devid = NULL;
    struct sndstat_info sinfo;
    oss_audioinfo ai;

    if (!strncmp(line, SNDSTAT_FV_BEGIN_STR, strlen(SNDSTAT_FV_BEGIN_STR))) {
      skipall = 1;
      continue;
    }
    if (!strncmp(line, SNDSTAT_BEGIN_STR, strlen(SNDSTAT_BEGIN_STR))) {
      is_ud = 0;
      skipall = 0;
      continue;
    }
    if (!strncmp(line, SNDSTAT_USER_BEGIN_STR,
                 strlen(SNDSTAT_USER_BEGIN_STR))) {
      is_ud = 1;
      skipall = 0;
      continue;
    }
    if (skipall || isblank(line[0]))
      continue;

    if (oss_sndstat_line_parse(line, is_ud, &amp;sinfo))
      continue;

    devinfop[collection_cnt].type = 0;
    switch (sinfo.type) {
    case CUBEB_DEVICE_TYPE_INPUT:
      if (type &amp; CUBEB_DEVICE_TYPE_OUTPUT)
        continue;
      break;
    case CUBEB_DEVICE_TYPE_OUTPUT:
      if (type &amp; CUBEB_DEVICE_TYPE_INPUT)
        continue;
      break;
    case 0:
      continue;
    }

    if (oss_probe_open(sinfo.devname, type, NULL, &amp;ai))
      continue;

    devid = oss_cubeb_devid_intern(context, sinfo.devname);
    if (devid == NULL)
      continue;

    devinfop[collection_cnt].device_id = strdup(sinfo.devname);
    asprintf((char **)&amp;devinfop[collection_cnt].friendly_name, &quot;%s: %s&quot;,
             sinfo.devname, sinfo.desc);
    devinfop[collection_cnt].group_id = strdup(sinfo.devname);
    devinfop[collection_cnt].vendor_name = NULL;
    if (devinfop[collection_cnt].device_id == NULL ||
        devinfop[collection_cnt].friendly_name == NULL ||
        devinfop[collection_cnt].group_id == NULL) {
      oss_free_cubeb_device_info_strings(&amp;devinfop[collection_cnt]);
      continue;
    }

    devinfop[collection_cnt].type = type;
    devinfop[collection_cnt].devid = devid;
    devinfop[collection_cnt].state = CUBEB_DEVICE_STATE_ENABLED;
    devinfop[collection_cnt].preferred =
        (sinfo.preferred) ? CUBEB_DEVICE_PREF_ALL : CUBEB_DEVICE_PREF_NONE;
    devinfop[collection_cnt].format = CUBEB_DEVICE_FMT_S16NE;
    devinfop[collection_cnt].default_format = CUBEB_DEVICE_FMT_S16NE;
    devinfop[collection_cnt].max_channels = ai.max_channels;
    devinfop[collection_cnt].default_rate = OSS_PREFER_RATE;
    devinfop[collection_cnt].max_rate = ai.max_rate;
    devinfop[collection_cnt].min_rate = ai.min_rate;
    devinfop[collection_cnt].latency_lo = 0;
    devinfop[collection_cnt].latency_hi = 0;

    collection_cnt++;

    void * newp =
        reallocarray(devinfop, collection_cnt + 1, sizeof(cubeb_device_info));
    if (newp == NULL)
      goto fail;
    devinfop = newp;
  }</code></pre></div>]]></description>
			<author><![CDATA[dummy@example.com (igorzwx)]]></author>
			<pubDate>Sun, 23 Nov 2025 15:29:44 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=59994#p59994</guid>
		</item>
	</channel>
</rss>
