Your Behringer/Midas X/M32 opens folders on a USB stick but shows no [..] row, so
there is no way back to the parent folder. This fixes it.
Prepare a USB stick on a Mac, plug it into an X32, and the USB browser will
happily descend into any folder — but once you are inside one you are stuck.
There is no [..] entry to climb back out.
The tell is that it usually works in exactly one folder: whichever one the console created itself.
macOS sets the hidden attribute on the . and .. entries of every
directory it creates on a FAT volume. The X32's browser filters hidden
entries, so .. never appears.
Directory entries as macOS writes them:
name=b'. ' attr=0x12 <- ATTR_DIRECTORY | ATTR_HIDDEN
name=b'.. ' attr=0x12
Microsoft's FAT specification says both entries carry ATTR_DIRECTORY and
nothing else — attribute 0x10. The console writes them that way, macOS does
not, and the X32 believes what it reads.
That is also why folders created on the console work. A directory created on the console has a zeroed FAT creation-date field, which macOS never writes, so it is easy to tell the two apart on a stick that has been through both.
Nothing here is an X32 bug: filtering hidden entries is reasonable, and the volume is still perfectly valid FAT. It is a disagreement about one bit.
Dry run first — the tool never writes without --apply:
sudo python3 x32-fat-dotfix.py X32TRACKS
Then fix it:
sudo python3 x32-fat-dotfix.py X32TRACKS --apply
--apply unmounts the volume, clears the bit, re-scans to confirm, and
remounts. Add -v to list every directory it touches.
The target can be a volume name, a /Volumes/... path, a /dev/diskNsM
node, or a raw FAT image file. On macOS, volume names are resolved through
diskutil; elsewhere, pass a device or image path. sudo is needed because
raw disk devices are not readable by ordinary users.
Re-run it whenever you add folders from the Mac. Every new directory the
Finder creates comes out hidden again. Copying files into an already-fixed
folder is safe — macOS does not rewrite . and .. after creation.
One bit, in the attribute byte of . and .. entries. Names, timestamps,
cluster pointers, the FATs and file data are all left alone, and directories
that are already correct are skipped. fsck_msdos reports the volume clean
afterwards.
It is still a raw write to a block device. Have a copy of anything you cannot re-rip.
Python 3.9+, no third-party packages. FAT12, FAT16 and FAT32; MBR-partitioned and unpartitioned volumes; images as well as devices.
macOS 26 (Darwin 25.5, the FSKit msdos implementation) against FAT32 with
8 KB clusters and FAT16 with 4 KB clusters, partitioned and not, including
directories spanning several clusters with subdirectories beyond the first,
and verified with fsck_msdos after each run. Fixed a real 16 GB stick for
an X32.
Two other things will make an X32 refuse WAV files, and neither looks like a filesystem problem:
- The sample rate must match the console's clock. A 48 kHz file will not play on a console running at 44.1 kHz. Use TNT Plus to convert your tracks to the correct format.
- Some encoders put a
LIST/INFOchunk betweenfmtanddata. ffmpeg does this by default. Simple WAV parsers expect a canonical 44-byte header.
MIT.