<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Audio on tsvinc</title>
		<link>https://tsvinc.dev/tags/audio/</link>
		<description>Recent content in Audio on tsvinc</description>
		<generator>Hugo</generator>
		<language>en-us</language>
		
		
		
		
			<lastBuildDate>Sun, 31 May 2026 00:00:00 +0000</lastBuildDate>
		
			<atom:link href="https://tsvinc.dev/tags/audio/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>FiiO X1 EQ table: seven register bytes my generator never read</title>
				<link>https://tsvinc.dev/posts/fiio-x1-seven-wrong-bytes-part-15/</link>
				<pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fiio-x1-seven-wrong-bytes-part-15/</guid>
				<description>&lt;p&gt;My project notes for the FiiO X1 have a gotchas section, and for a while one line in it was wrong in a way that sounded careful. It said that the EQ coefficients I had generated in Q23, a 24-bit fixed-point format, broke the boot, so the PCM5142, the player&#39;s DAC chip, probably had constraints beyond the math of the Audio EQ Cookbook, the standard recipe for these filters.&lt;/p&gt;&#xA;&lt;p&gt;It reads like a finding. It was a shrug with a datasheet attached. I distrust a root cause the way I distrust a datasheet, by how much it explains without having been tested, and this one explained everything and had been tested against nothing.&lt;/p&gt;</description>
			</item>
			<item>
				<title>FiiO X1 PCM5142 DSP blocks: the flat head I believed</title>
				<link>https://tsvinc.dev/posts/fiio-x1-flat-that-lied-part-17/</link>
				<pubDate>Sun, 31 May 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fiio-x1-flat-that-lied-part-17/</guid>
				<description>&lt;p&gt;For the length of one hex dump, three blocks of DAC coefficients in the FiiO X1&#39;s firmware were solved. I had read the first 96 bytes of each, seen nothing but unity filters, which pass the signal through unchanged, and written down that all three were a flat, do-nothing initialization. Then the decoder read the rest.&lt;/p&gt;&#xA;&lt;p&gt;The X1 is a pocket music player from 2014 whose sound comes out of a TI PCM5142, a DAC with a small programmable DSP inside it. The firmware, HiBy&#39;s, on the µC/OS-II kernel, talks to the DAC over a three-wire serial line it drives by toggling GPIO pins; &lt;a href=&#34;https://tsvinc.dev/posts/fiio-x1-hidden-dac-part-9/&#34;&gt;Part 9&lt;/a&gt; found that line and the equalizer table behind it, and &lt;a href=&#34;https://tsvinc.dev/posts/fiio-x1-seven-wrong-bytes-part-15/&#34;&gt;Part 15&lt;/a&gt; decoded that table. My notes on the audio code still listed three other blocks as undecoded: 2,708 bytes each, sitting just below the equalizer table in memory, streamed to the DAC every time the firmware opens an audio stream. Nobody puts 8 KB of nothing in a firmware image and then sends it to a chip on every stream, which should have been my first clue.&lt;/p&gt;</description>
			</item>
			<item>
				<title>FiiO X1 bare-metal audio: four GPIO offsets, all wrong</title>
				<link>https://tsvinc.dev/posts/fiio-x1-three-wrong-numbers-part-14/</link>
				<pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fiio-x1-three-wrong-numbers-part-14/</guid>
				<description>&lt;p&gt;The build was clean: 18,672 bytes, nothing worse than unused-function warnings. A clean build is the most reassuring thing a compiler can say and the least informative, and this one was vouching for an audio driver that, as written, could not have made a sound.&lt;/p&gt;&#xA;&lt;p&gt;The driver belongs to a bootloader for the FiiO X1, a $99 music player on an Ingenic JZ4760B MIPS chip. &lt;a href=&#34;https://tsvinc.dev/posts/fiio-x1-twelve-kilobytes-part-13/&#34;&gt;Part 13&lt;/a&gt; wrote that bootloader: it runs from the SD card as &lt;code&gt;factory.x1&lt;/code&gt;, a file the stock loader executes without checking, and it can load an image of Rockbox, the open-source player firmware. The next step toward Rockbox is sound, and the smallest honest test of sound is a sine wave from bare-metal code: no codecs, no DMA, no mixer. As far as I knew then, that meant three things the stock loader, which doesn&#39;t play music, has no reason to set up: an I2C controller to configure the TI PCM5142 DAC, the AIC (the chip&#39;s audio interface) to send it I2S samples, and the GPIO pins both of them need.&lt;/p&gt;</description>
			</item>
			<item>
				<title>FiiO X1 EQ presets: floats in .data, not a NAND cache</title>
				<link>https://tsvinc.dev/posts/fiio-x1-ten-bands-part-12/</link>
				<pubDate>Sun, 25 Jan 2026 00:00:00 +0000</pubDate>
				<guid>https://tsvinc.dev/posts/fiio-x1-ten-bands-part-12/</guid>
				<description>&lt;p&gt;Where does a music player keep its equalizer presets? On the FiiO X1 I had a confident answer, a cache on the flash chip that the firmware writes once and trusts forever, and the answer had cost me an evening of flashing.&lt;/p&gt;&#xA;&lt;p&gt;The X1 is a $99 player on an Ingenic JZ4760B MIPS chip, running firmware that HiBy wrote on the µC/OS-II real-time kernel. In &lt;a href=&#34;https://tsvinc.dev/posts/fiio-x1-the-patcher-part-10/&#34;&gt;Part 10&lt;/a&gt; I built a patcher that rewrites &lt;code&gt;sys.bin&lt;/code&gt;, the firmware binary inside the official update file &lt;code&gt;x1.fw&lt;/code&gt;, and the one change I wanted most showed up once, one slot off, and never again after I fixed the slot: I patched the preset gains, flashed, opened the EQ screen, and Rock still read all zeros. Meanwhile my custom EQ setting and my theme choice had survived the flash. So I wrote down a theory: the presets live in a cache on the NAND&#39;s &lt;code&gt;userdata&lt;/code&gt; partition, and the values in the binary only matter the first time. This part reads the firmware&#39;s EQ code in Ghidra, a disassembler and decompiler, instead of guessing at it.&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
