<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Walkman on ntzyz&#39;s space</title>
        <link>/categories/walkman/</link>
        <description>Recent content in Walkman on ntzyz&#39;s space</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Wed, 11 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="/categories/walkman/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Walkman Hands-On: Giving a Ten-Year-Old Gadget a New UI (Part 1)</title>
            <link>/post/walkman-and-musicos-chapter-1/</link>
            <pubDate>Wed, 11 Nov 2026 00:00:00 +0000</pubDate>
            <guid>/post/walkman-and-musicos-chapter-1/</guid>
            <description>&lt;img src=&#34;/post/walkman-and-musicos-chapter-1/cover.webp&#34; alt=&#34;Featured image of post Walkman Hands-On: Giving a Ten-Year-Old Gadget a New UI (Part 1)&#34; /&gt;&lt;p&gt;A while back I got one of those sudden itches to pick up a Walkman, &lt;del&gt;having been a loyal NW-series owner back in the day&lt;/del&gt;. Once it arrived I did some reading and found the community has already been through all of this: custom firmwares like Walkman One, various UI tweaks. Honestly, at first I didn&amp;rsquo;t see much worth tinkering with. I flashed Walkman One and then it just sat there gathering dust. Partly because having to use wired headphones is a pain, and partly because the firmware had started having compatibility trouble with my AirPods Pro 2: they&amp;rsquo;d pair, and then play nothing at all. So it went back in the drawer.&lt;/p&gt;&#xA;&lt;p&gt;Then over the Mid-Autumn holiday I remembered I still had the thing. It bugged me, sitting there useless. So I dug it out to see what I could actually do with it, and noticed that these custom firmwares quietly switch on the adbd that Sony left behind. Suddenly this got interesting: with a root shell, the whole machine is mine. I can do whatever I want.&lt;/p&gt;&#xA;&lt;p&gt;First, a quick look at what this thing is:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;&#xA;&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24&#xA;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td class=&#34;lntd&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ adb devices&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;List of devices attached&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;10453485000783&#x9;device&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ adb shell&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/meminfo | head -n 3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MemTotal:         &lt;span class=&#34;m&#34;&gt;467984&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MemFree:           &lt;span class=&#34;m&#34;&gt;44644&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Buffers:           &lt;span class=&#34;m&#34;&gt;21532&lt;/span&gt; kB&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/cmdline&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/null &lt;span class=&#34;nv&#34;&gt;root&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/ram &lt;span class=&#34;nv&#34;&gt;vmalloc&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;496M &lt;span class=&#34;nv&#34;&gt;slub_max_order&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;slub_debug&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;O  &lt;span class=&#34;nv&#34;&gt;lcm&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1-otm8018b_vdo_cmd &lt;span class=&#34;nv&#34;&gt;fps&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6023&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;vram&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;6291456&lt;/span&gt; androidboot.selinux&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;disabled bootprof.pl_t&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1145&lt;/span&gt; bootprof.lk_t&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2137&lt;/span&gt; printk.disable_uart&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;boot_reason&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;4&lt;/span&gt; icx_pm_helper.icx_sysinfo&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x00000000 icx_pm_helper.icx_modelid&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x20000007 mmc_core.emmc_boot_serial&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x96615529 icx_pm_helper.icx_boot_option&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; leds_drv.brightness&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;255&lt;/span&gt; androidboot.serialno&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;10453485000783&lt;/span&gt; androidboot.bootreason&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;wdt_by_pass_pwk icx_pm_helper.icx_boot_reason&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;0x1 androidboot.hardware&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;icx androidboot.console&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;ttyMT1 androidboot.printk&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; androidboot.bid3&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# cat /proc/cpuinfo&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Processor&#x9;: ARMv7 Processor rev &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;v7l&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Processor&#x9;: ARMv7 Processor rev &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;v7l&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;...&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hardware&#x9;: MT8590&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Revision&#x9;: &lt;span class=&#34;m&#34;&gt;0000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Serial&#x9;&#x9;: &lt;span class=&#34;m&#34;&gt;0000000000000000&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# ls | tr &amp;#39;\n&amp;#39; &amp;#39; &amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bin boot boot.sh bootshow bootui build.prop cache contents contents_ext contents_ext1 data db default.prop dev emmc@android emmc@bootimg emmc@cache emmc@cm4 emmc@contents emmc@db emmc@dkb emmc@ebr1 emmc@expdb emmc@kb emmc@logo emmc@misc emmc@nvp emmc@nvram emmc@option1 emmc@option2 emmc@option3 emmc@pro_info emmc@protect_f emmc@protect_s emmc@recovery emmc@sec_ro emmc@seccfg emmc@tee1 emmc@tee2 emmc@uboot emmc@usrdata emmc@var emmc@xhrome etc factory file_contexts home init init.hagoromo.rc init.project.rc init.rc init.real init.usbcfg.rc init.usbcfgdmp.rc install_update_script lib newroot oem_cast_shlib opt1 opt2 opt3 proc res root sbin sys system tmp ueventd.audiodefault-b1.rc ueventd.audiodefault-b2.rc ueventd.audiodefault-b3.rc ueventd.icx.rc ueventd.rc usr var xbin&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;Looks like a fairly ordinary Linux with a very Android-flavoured rootfs. Which raises the question: if I want to put something on this screen, how would I even go about it?&lt;/p&gt;&#xA;&lt;p&gt;A quick search showed someone in the community had already done it: &lt;a class=&#34;link&#34; href=&#34;https://github.com/unknown321/wampy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;wampy&lt;/a&gt;. In short, Sony&amp;rsquo;s main player binary &lt;code&gt;HgrmMediaPlayerApp&lt;/code&gt; is a Qt app, and the author cleverly used the Qt eglfs platform plugin to squeeze his own code into that process, then called &lt;code&gt;QWindow::hide()&lt;/code&gt; to hide the original window. The screen is free again. To make it easy for others to build on his work, he also provided a &lt;code&gt;/tmp/wampy.sock&lt;/code&gt; plus a &lt;code&gt;wampyctl&lt;/code&gt; command, giving the rest of us a much friendlier way in.&lt;/p&gt;&#xA;&lt;p&gt;So running things is solved. What&amp;rsquo;s left is deciding what to run. DOOM came to mind first, but an FPS on that little touchscreen is a bit rough to control (haha). Then I thought of another classic that has been ported to everything: SDLPAL.&lt;/p&gt;&#xA;&lt;p&gt;The first thing SDLPAL needs is SDL working on this platform. Doing that properly means writing an SDL video driver, which for a little experiment like this isn&amp;rsquo;t really worth it. But wampy&amp;rsquo;s cassette renderer shows the trick: to get pixels on screen you can just build a bitmap in memory and treat it as a texture. Which is to say, run SDL in pure CPU mode, draw everything into a 480x800 &lt;code&gt;SDL_Surface&lt;/code&gt;, then push that texture to the panel with &lt;code&gt;eglSwapBuffers&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;To check the idea I just had DSH write it (actually typing the code out by hand is dull, isn&amp;rsquo;t it). Getting the basic shapes up on screen went smoothly:&lt;/p&gt;&#xA;&lt;figure class=&#34;video-figure&#34;&gt;&#xA;    &lt;video&#xA;        controls&#xA;        playsinline&#xA;        preload=&#34;metadata&#34;&#xA;        src=&#34;/post/walkman-and-musicos-chapter-1/sdl-port.mp4&#34;&#xA;        &#xA;        &#xA;        &#xA;    &gt;&#xA;        &lt;p&gt;你的浏览器不支持 HTML5 视频，可以&lt;a href=&#34;/post/walkman-and-musicos-chapter-1/sdl-port.mp4&#34;&gt;直接下载&lt;/a&gt;。&lt;/p&gt;&#xA;    &lt;/video&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&#xA;&lt;p&gt;With the display sorted, not much was left. Next I had the AI handle touch and button input, cross-compiled SDL2 statically with zig (&lt;code&gt;-target arm-linux-gnueabihf.2.23&lt;/code&gt;), copied my game files onto the device, and just like that the game was running.&lt;/p&gt;&#xA;&lt;figure class=&#34;video-figure&#34;&gt;&#xA;    &lt;video&#xA;        controls&#xA;        playsinline&#xA;        preload=&#34;metadata&#34;&#xA;        src=&#34;/post/walkman-and-musicos-chapter-1/sdlpal-run.mp4&#34;&#xA;        &#xA;        &#xA;        &#xA;    &gt;&#xA;        &lt;p&gt;你的浏览器不支持 HTML5 视频，可以&lt;a href=&#34;/post/walkman-and-musicos-chapter-1/sdlpal-run.mp4&#34;&gt;直接下载&lt;/a&gt;。&lt;/p&gt;&#xA;    &lt;/video&gt;&#xA;    &#xA;&lt;/figure&gt;&#xA;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;Friend: now that&amp;rsquo;s a hifi way to knock your head&lt;/p&gt;&#xA;&lt;p&gt;Friend: good sound is what makes a good head&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;It wasn&amp;rsquo;t nearly that smooth, of course. Plenty of potholes along the way. Here&amp;rsquo;s a quick list of what broke and how it got fixed; I don&amp;rsquo;t remember the details well enough anymore, so I had the AI summarise them for me:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Events did nothing&lt;/strong&gt;: pushing &lt;code&gt;SDL_KEYDOWN&lt;/code&gt; into SDL&amp;rsquo;s queue had no effect. SDLPAL reads input by polling &lt;code&gt;SDL_GetKeyboardState()&lt;/code&gt;, so we had to write the keyboard state directly.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Key passthrough&lt;/strong&gt;: hiding the window only stops the drawing; Sony&amp;rsquo;s &lt;code&gt;KeyService&lt;/code&gt; still reads the same evdev node. Pressing Play did nothing in the game and started an MP3 instead → &lt;code&gt;EVIOCGRAB&lt;/code&gt; on &lt;code&gt;event0/1/4&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Red and blue swapped&lt;/strong&gt;: &lt;code&gt;SDL_PIXELFORMAT_ARGB8888&lt;/code&gt; is B,G,R,A in little-endian memory, so uploading it as &lt;code&gt;GL_RGBA&lt;/code&gt; inverted the colours → &lt;code&gt;RGBA32&lt;/code&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Touch was way off&lt;/strong&gt;: the panel reports 0..959 × 0..1599, not 480×800, so the red dot in the help overlay had nothing to do with my finger.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Who owns the sound card&lt;/strong&gt;: SDL&amp;rsquo;s ALSA backend never actually made it into the cross build; the kernel&amp;rsquo;s OSS compat layer works with &lt;code&gt;AUDIODEV=/dev/snd/dsp&lt;/code&gt;. If Sony is playing, pause it first; if that doesn&amp;rsquo;t help, run muted.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;By this point a rather bold idea had hit me, maybe even a slightly cocky one. I don&amp;rsquo;t think Sony&amp;rsquo;s system is all that pleasant to use. And with some AI magic on my side, plus the fact that I know my way around Linux and audio codecs (not an expert, but enough to get by), why not build a userspace player that actually suits my own tastes?&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
