<?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=7620&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Dev1 Galaxy Forum / Chasing the Fox (Caccia alla volpe)]]></title>
		<link>https://dev1galaxy.org/viewtopic.php?id=7620</link>
		<description><![CDATA[The most recent posts in Chasing the Fox (Caccia alla volpe).]]></description>
		<lastBuildDate>Thu, 27 Nov 2025 18:47:37 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[Chasing the Fox (Caccia alla volpe)]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=60153#p60153</link>
			<description><![CDATA[<div class="quotebox"><blockquote><div><p>So after the fox, after the fox<br />Off to the hunt with chains and locks<br />So after the fox, after the fox<br />Someone is always chasing after the fox</p><p><strong>After the Fox</strong> (1966) _https://www.youtube.com/watch?v=MrQl0VsQYtw</p></div></blockquote></div><h5>📖 Manual: &quot;We Can’t Yet Prove Firefox Is Resampling… But We’ll Keep Trying&quot;</h5><p>For the truly dedicated — those who believe their audio deserves better.</p><p><strong>🔧 Step 0: Lock It Down</strong><br />Before we begin, <strong>disable the PulseAudio backend</strong> - yes, even the <em>rusty</em> one:</p><ol class="decimal"><li><p>Open Firefox and type <span class="bbc">about:config</span>&#160; in the address bar</p></li><li><p>Search: <span class="bbc">media.cubeb.backend</span></p></li><li><p>Click <strong>+</strong>, set type to <span class="bbc">string</span>, value to <span class="bbc">alsa</span></p></li></ol><p>Now Firefox talks <strong>directly to ALSA</strong> - no middlemen.</p><div class="quotebox"><blockquote><div><p>✅ You’ve just sidestepped a surveillance-level audio framework.</p></div></blockquote></div><p><strong>🕵️ Step 1: The Smoking Gun</strong><br />Firefox uses <strong>Speex Resampler</strong> under the hood - yes, <em>that</em> Speex.<br />It’s in the code: <span class="bbc">AudioConverter.cpp</span> includes <span class="bbc">&lt;speex/speex_resampler.h&gt;</span>.</p><div class="quotebox"><blockquote><div><p>_https://searchfox.org/firefox-main/source/dom/media/AudioConverter.cpp</p><div class="codebox"><pre><code>#include &quot;AudioConverter.h&quot;

#include &lt;speex/speex_resampler.h&gt; </code></pre></div></div></blockquote></div><p>But here’s the twist:</p><ul><li><p>On <strong>macOS</strong>, cubeb logs:<br /><span class="bbc">Input and output sample-rate match, target rate of 48000Hz</span></p></li><li><p>On <strong>Linux</strong>? Silence.<br />Nothing. Nada. Zilch.</p></li></ul><div class="quotebox"><blockquote><div><p>🚨 <strong>Suspicious?</strong><br />Or is Mozilla simply not telling Linux users what it’s up to?</p></div></blockquote></div><p>macOS Firefox logs:</p><div class="codebox"><pre><code>➤ MOZ_LOG=&quot;MediaDecoder:4,cubeb:5&quot; stdbuf -oL /Applications/Firefox\ Developer\ Edition.app/Contents/MacOS/firefox 2&gt;&amp;1 https://youtu.be/uO6jfQ5tQHM | ggrep  --line-buffered -E &quot;MetadataLoaded.*rate=|FirstFrameLoaded.*rate=|CubebStreamInit output stream rate|target rate|Output hardware&quot; | ggrep -v &quot;hasVideo=0&quot;
[Child 4501: Main Thread]: D/MediaDecoder MediaDecoder[11631e700] MetadataLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1
[Child 4501: Main Thread]: D/MediaDecoder MediaDecoder[116f37300] MetadataLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1
[Child 4501: Main Thread]: D/MediaDecoder MediaDecoder[116f37300] FirstFrameLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1 mPlayState=PLAY_STATE_LOADING transportSeekable=1
[Child 4501: MediaDecoderStateMachine #1]: I/cubeb CubebStreamInit output stream rate 48000
[Parent 4486: AudioIPC Server RPC]: E/cubeb mod.rs:3995: (0x183e31c00) Output hardware description: AudioStreamBasicDescription { mSampleRate: 96000.0, mFormatID: 1819304813, mFormatFlags: 9, mBytesPerPacket: 8, mFramesPerPacket: 1, mBytesPerFrame: 8, mChannelsPerFrame: 2, mBitsPerChannel: 32, mReserved: 0 }
[Parent 4486: AudioIPC Server RPC]: E/cubeb cubeb_resampler_internal.h:553:Input and output sample-rate match, target rate of 48000Hz</code></pre></div><p>On macOS, Firefox appears to feign transparency and user-friendliness. But macOS isn’t quite Linux: applications ought to behave in a civilised manner.</p><p>Right. So Firefox has its own resampler, and cubeb has its own as well - meaning the audio could be quietly upsampled and downsampled like some sort of secret internal game of pass-the-parcel, and we’d never even see it in the logs.</p><p>Typical, really. Everything’s transparent and user-friendly - just not <em>actually</em>.</p><p><strong>What&#039;s Actually Happening</strong></p><ol class="decimal"><li><p><strong>Resampling</strong>: Cubeb uses its Speex-based resampler (<span class="bbc">cubeb_resampler_internal.h:199–207</span>).</p></li><li><p><strong>Stream initialisation</strong>: Once the target rate is determined, Cubeb sets up the stream at 48kHz (<span class="bbc">cubeb_resampler_internal.h:561–577</span>).</p></li><li><p><strong>Passthrough mode</strong>: When input and output rates match, Cubeb uses a passthrough resampler that simply forwards buffers without conversion (<span class="bbc">cubeb_resampler_internal.h:548–556</span>).</p></li></ol><p>The resampler selection logic in <span class="bbc">cubeb_resampler_create_internal()</span> confirms this:</p><div class="codebox"><pre><code>// Check if rates match - if so, use passthrough  
if (((input_params &amp;&amp; input_params-&gt;rate == target_rate) &amp;&amp;  
     (output_params &amp;&amp; output_params-&gt;rate == target_rate)) ||  
    (input_params &amp;&amp; !output_params &amp;&amp; (input_params-&gt;rate == target_rate)) ||  
    (output_params &amp;&amp; !input_params &amp;&amp;  
     (output_params-&gt;rate == target_rate))) {  
  LOG(&quot;Input and output sample-rate match, target rate of %dHz&quot;, target_rate);  
  return new passthrough_resampler&lt;T&gt;(...);  
}</code></pre></div><p>When rates don’t match, it creates a <span class="bbc">cubeb_resampler_speex_one_way</span> for conversion (<span class="bbc">cubeb_resampler_internal.h:187–203</span>).</p><p><strong>🔍 Step 2: The Bit Depth Conspiracy</strong><br />Firefox converts <strong>everything</strong> to <strong>32-bit float</strong> - internally.</p><p>But let’s be honest:</p><ul><li><p><strong>20 years ago</strong>, <span class="bbc">fftrate</span> used <strong>64-bit float</strong>.</p></li><li><p><strong>Today</strong>, serious audio tools use <strong>128-bit float</strong> or more.</p></li></ul><p>And what does Firefox do?</p><div class="codebox"><pre><code>sample spec: float32le 2ch 48000Hz</code></pre></div><div class="quotebox"><blockquote><div><p>🧠 <strong>32-bit float</strong> - the <strong>Stone Age</strong> of precision.<br />It works, but is it <em>good enough</em>?</p></div></blockquote></div><p>This isn’t about whether it functions — it’s whether it respects the medium. Firefox settles for the lowest common denominator, even when the hardware and OS are ready to do better.</p><p><strong>🧩 Step 3: Who’s Really Resampling?</strong><br />You’ve set:</p><div class="codebox"><pre><code>media.resampling.enabled   false</code></pre></div><p>So Firefox <strong>should not resample</strong>.</p><p>Logs show:</p><div class="codebox"><pre><code>MetadataLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1
FirstFrameLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1 
CubebStreamInit output stream rate 48000</code></pre></div><p><strong>🛠️ Final Command: Firefox logging together with fftrate logging</strong></p><div class="codebox"><pre><code>➤ MOZ_LOG=&quot;MediaDecoder:4,cubeb:5&quot; stdbuf -oL firefox 2&gt;&amp;1 https://youtu.be/uO6jfQ5tQHM | grep  --line-buffered -E &quot;MetadataLoaded.*rate=|FirstFrameLoaded.*rate=|CubebStreamInit output stream rate|target rate|Output hardware|Input|Output|Rates&quot; | grep -v &quot;hasVideo=0&quot;
[Child 13197: Main Thread]: D/MediaDecoder MediaDecoder[7f6c62c17900] MetadataLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1
Input:  44100 Hz, 2 ch, &#039;s32_le&#039; (0xa): dummy = 0, period = 1764
Output: 48000 Hz, 2 ch, &#039;s16_le&#039; (0x2): dummy = 0, period = 1920
Rates:  44100 --&gt; 48000 (J: 0.00%, T: FFT, W: Vorbis)
[Child 13197: Main Thread]: D/MediaDecoder MediaDecoder[7f6c62c17900] FirstFrameLoaded, channels=2 rate=48000 hasAudio=1 hasVideo=1 mPlayState=PLAY_STATE_LOADING transportSeekable=1
[Child 13197: MediaDecoderStateMachine #1]: I/cubeb CubebStreamInit output stream rate 48000
Input:  48000 Hz, 2 ch, &#039;s32_le&#039; (0xa): dummy = 0, period = 1920
Output: 48000 Hz, 2 ch, &#039;s16_le&#039; (0x2): dummy = 0, period = 1920
Rates:  48000 --&gt; 48000 (J: 0.00%, T: None, W: Planar)</code></pre></div><p>This reflects only the observable behaviour. The full pipeline? Still hidden. As usual.</p><p><strong>The Mystery Audio Stream</strong></p><div class="codebox"><pre><code>Input:  44100 Hz, 2 ch, &#039;s32_le&#039; (0xa): dummy = 0, period = 1764</code></pre></div><p><strong>The Short and Curious Tale</strong><br />Right then, here&#039;s what&#039;s happening: Firefox, being a proper gentleman, politely taps your audio system on the shoulder to ask, &quot;I say, what sample rate do you prefer?&quot; This happens through Cubeb&#039;s <span class="bbc">alsa_get_preferred_sample_rate()</span> function.</p><p>Firefox tries 44.1kHz first (a rather common rate, don&#039;t you know), but your dmix plugin, being a bit of a stickler for rules, insists on 48kHz. So ALSA’s resampler steps in like a proper butler, converting the stream—even though Firefox requested <span class="bbc">SND_PCM_NO_AUTO_RESAMPLE</span>.</p><p>The &quot;dummy = 0&quot; in your logs? That&#039;s just ALSA&#039;s way of saying &quot;This is a real device, gov&#039;nor, not some test dummy.&quot;</p><p><strong>Why This Isn&#039;t Your YouTube Video</strong><br />This probing happens before any actual playback — it&#039;s merely Firefox checking what your audio system can handle. The actual YouTube stream will use whatever rate this probe determines (likely 48kHz in your case).</p><p><strong>The Bottom Line</strong><br />Perfectly normal behaviour, old chap! Just Firefox being thorough and your dmix plugin being particular. The resampling you see is ALSA doing its thing, completely separate from Cubeb&#039;s internal workings. Your hardware supporting 44.1kHz doesn&#039;t stop dmix from having its own ideas about proper audio rates.</p><p><strong>Notes</strong></p><ul><li><p>This probe stream mechanism is used across all Cubeb backends for capability detection.</p></li><li><p>The format <span class="bbc">&#039;s32_le&#039;</span> is 32-bit signed integer.</p></li><li><p>The <span class="bbc">&quot;T: FFT&quot;</span> indicates ALSA&#039;s FFT-based resampling algorithm.</p></li><li><p><span class="bbc">&quot;J: 0.00%&quot;</span> shows minimal jitter — the conversion is working rather well indeed.</p></li></ul><p><strong>🧙♂️ Conclusion</strong><br />We cannot <em>prove</em> Firefox is resampling — because <strong>it doesn’t log it</strong>.</p><p>But we know:</p><ul><li><p>It uses <strong>Speex resampler</strong>.</p></li><li><p>It <strong>hides resampling logs on Linux</strong>.</p></li></ul><p>So is it resampling?</p><div class="quotebox"><blockquote><div><p>🔎 <strong>We may never know.</strong><br />But we’ll keep watching.</p></div></blockquote></div><p><strong>Citations</strong></p><p><strong>File:</strong> src/cubeb_alsa.c (L1228-1272)</p><div class="codebox"><pre class="vscroll"><code>static int
alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
{
  (void)ctx;
  int r, dir;
  snd_pcm_t * pcm;
  snd_pcm_hw_params_t * hw_params;

  snd_pcm_hw_params_alloca(&amp;hw_params);

  /* get a pcm, disabling resampling, so we get a rate the
   * hardware/dmix/pulse/etc. supports. */
  r = WRAP(snd_pcm_open)(&amp;pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK,
                         SND_PCM_NO_AUTO_RESAMPLE);
  if (r &lt; 0) {
    return CUBEB_ERROR;
  }

  r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params);
  if (r &lt; 0) {
    WRAP(snd_pcm_close)(pcm);
    return CUBEB_ERROR;
  }

  r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &amp;dir);
  if (r &gt;= 0) {
    /* There is a default rate: use it. */
    WRAP(snd_pcm_close)(pcm);
    return CUBEB_OK;
  }

  /* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */
  *rate = 44100;

  r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL);
  if (r &lt; 0) {
    WRAP(snd_pcm_close)(pcm);
    return CUBEB_ERROR;
  }

  WRAP(snd_pcm_close)(pcm);

  return CUBEB_OK;
}</code></pre></div>]]></description>
			<author><![CDATA[dummy@example.com (igorzwx)]]></author>
			<pubDate>Thu, 27 Nov 2025 18:47:37 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=60153#p60153</guid>
		</item>
	</channel>
</rss>
