-
-
Notifications
You must be signed in to change notification settings - Fork 1
01 overview
CHD Studio is a high-performance Windows desktop utility designed to streamline the conversion of various disk image formats into the Compressed Hunks of Data (CHD) format — the format used by MAME, and increasingly by emulation frontends for PlayStation, Dreamcast, and other systems.
Developed by Pure Logic Code, the application combines a modern cross-platform Avalonia dashboard with battle-tested MAME tooling (chdman) and pure-C# libraries (CHDSharp, CCDSharp, CSOSharp, PBPSharp, MDSSharp, ISZSharp) for a fully local, offline-capable conversion experience.
- Dual-pane interface — settings and file list on the left, real-time terminal-style log on the right.
- Interactive file selection — automatically scans folders; the user picks exactly which files to process via a detailed list with checkboxes.
-
Chunked file loading — directory scans with thousands of files are loaded in chunks of 100 items at background priority to keep the UI responsive (
MainWindow.axaml.cs:820–975). - Resizable layout — built-in grid splitter between file explorer and log view.
-
Native x64 & ARM64 — on Windows,
AppConfig.IsArm64selectschdman_arm64.exe/7za_arm64.exeon ARM64 hardware,chdman.exe/7za.exeelsewhere (AppConfig.cs:17–29). Linux/macOS use the bundled managed encoder plus the platform7zz.
- Automated batch processing — convert entire directories with real-time progress, immediate cancellation, and per-file timeouts.
-
Built-in encoder — the CHDSharp library (CHDSharpLib 1.4.3) encodes in-process: the automatic fallback behind chdman on Windows and the only encoder on Linux/macOS. Its output is byte-identical to
chdman0.289, and because it is managed code there is no encoder executable to ship or probe. -
Recursive structure preservation — the output folder mirrors the input folder's directory hierarchy (
PathUtils.GetSafeRelativePath). -
Robust extraction — CHD →
.cue(CD),.iso(DVD),.gdi(Dreamcast/Naomi),.img(HDD),.avi(laserdisc A/V), with automatic flag-based command detection via CHDSharp. Laserdisc A/V CHDs extract in-process, so they no longer need chdman. -
Laserdisc support —
.aviinputs convert withcreateld(A/Vavhucodec), and A/V CHDs extract back to AVI, all through the built-in encoder. -
Checksum reports — optional whole-image plus per-track SHA-1/CRC-32/XXH3 report (
.checksums.txt) written next to each verified CHD. - CHD Explorer — browse the file system inside a CHD and read an Image Info report (header, codecs, metadata, tracks, per-codec hunk distribution).
-
Archive integration —
.zip,.7z,.rarare extracted and processed transparently (SharpCompress, with a bundled 7-Zip fallback —7zaon Windows,7zzon Linux/macOS — for archives the built-in extractor cannot read); multi-part RAR sets (.partNN.rar, renamed.001volumes) are decoded from their first volume. -
CloneCD support —
.ccdsets are parsed by CCDSharp and converted via an auto-generated CUE/BIN. -
CSO decompression —
.cso/.cisovia CSOSharp (deflate/zlib and LZ4). -
PBP extraction — PlayStation
.pbpvia PBPSharp; PSP-homebrew-style files (no PlayStation disc image) are detected and skipped with a clear message. - Smart CUE normalization — encoding detection (UTF-8, Shift-JIS, Korean CP949, Cyrillic CP1251, Latin-1, …), UTF-8 BOM stripping, case-insensitive and zero-padding-tolerant reference resolution, canonicalization into a self-contained work directory.
- Archive dependency validation — cue/GDI/TOC entries extracted from archives are validated up front; entries with missing referenced files are skipped with a warning instead of failing inside chdman.
- MP3 audio track support — cue/MP3 sets are decoded to chdman-compatible WAV (44.1 kHz, 16-bit, stereo) automatically, with a built-in decoder fallback.
-
bin-only archives — archives containing only
.binfiles get an auto-generated MODE2/2352 cue (with MODE1/2352 fallback) and convert automatically.
A file's extension is the least reliable thing about it. Every input's leading bytes are inspected before the extension is trusted (MainWindow.TryResolveByContentAsync), which turns several "corrupt file" failures into successful conversions.
-
Raw CD dumps with the wrong name — a 2352-bytes-per-sector CD dump saved as
.iso,.img,.binor.iszis recognised from its sector sync mark and mode byte and converted as the CD it is, with a generated cue. Previously these went tocreatedvd/createhdand failed onData size ... is not divisible by sector size. -
Disc images wearing an archive extension — a
.rar/.zipthat is really a plain disc image, or a byte-split set that was never an archive, is detected and converted instead of being reported as corrupt. -
Bare
.binfiles — accepted as a standalone input with a generated cue. When a sibling.cue/.ccd/.mdsalready covers the.bin, it is dropped from the batch so the disc converts once, through its descriptor (InputFileFilter). - Honest reporting — a truncated download, a mislabelled file and a genuinely unsupported format each read differently in the log, naming what was found and what to do about it.
-
Alcohol 120% —
.mds/.mdfsets convert directly. The descriptor's track table is parsed into a matching cue; images storing 2448 or 2368 bytes per sector have their subchannel tail stripped first (chdman cannot read those); a.mdfthat is really an ISO converts as a DVD image. -
ISZ decompression — UltraISO
.iszimages are decompressed in-process (zlib, bzip2, stored and all-zero chunks), including images split across.i01/.i02or.part01.isz/.part001.iszsegments. The obfuscated tables, stripped bzip2 headers and no-chunk-table layout real files use are handled, UltraISO's checksum is validated when present, segments are matched by volume serial number, a missing one is named, and an encrypted image says so. -
ECM decoding —
.ecmfiles are decoded in-process, with no external tool to install. The per-sector EDC and Reed-Solomon parity that ECM discards are regenerated, verified byte for byte against Neill Corlett's reference implementation. -
Split volume sets — images split into
.001/.002or.i00/.i01pieces are rejoined before conversion; a set with a missing part is reported rather than handed to chdman half-complete. Only the first volume appears in the file list. -
Split-track discs — a
(Track 1),(Track 2), … bin set gets a multi-track cue, so discs with CDDA keep their audio instead of converting as a single data track. -
Broken cue descriptors — a
FILEline naming something that is not there is resolved against what is actually on disk: by name beside the cue, by extension swap, and for a single-FILE cue by elimination. Audio tracks and multi-FILE cues are left alone, because guessing there could silently drop a track.
-
A good CHD is never destroyed — conversions are written to a
.chdtmpstaging file and moved into place only on success. chdman runs with-fand truncates its output before it can fail, so without staging a second input mapping to the same output name could wipe out a working CHD produced by the first. -
Output collision warnings — the output name comes from the input's base name, so
Game.cue,Game.zipandGame.ccdin one folder all targetGame.chd. Colliding inputs are reported at the start of the batch, before time is spent on them; archives are judged by what they actually contain, and any duplicate output produced later in the batch is reported and skipped instead of silently replacing the first. -
In-place conversion and extraction — the output folder may be the same as the source folder, or inside it. Conversion is inherently safe there (the output is always
<base>.chd, which is never an input, and it is staged before replacing anything). Extraction takes the CHD's base name, so when its output would land on existing files (a cue/bin or gdi/bin set included) the whole disc is diverted into a subfolder named after it instead. Nothing is overwritten, nothing is asked, and the layout only changes for the discs that actually clash. - Disk-space preflight — free space on the output drive is checked immediately before chdman starts; clearly insufficient space skips the file with both figures named instead of failing an hour in.
-
Output-folder preflight — the destination is probed for write access before a batch starts; an unwritable folder (e.g. inside
Program Fileswithout elevation) produces one clear message instead of a run of per-file "Permission denied" failures. -
chdman-safe path handling — non-ASCII characters anywhere along a path (
C:\Users\Kauê Chacon\...,D:\Emulátory\...) and paths at or beyond MAX_PATH are routed through short ASCII staging directories, because older chdman builds mangle or cannot open such paths. Cue work directories avoid a non-ASCII system temp folder the same way. -
Crash-aware error reporting — when Windows kills chdman outright (e.g. exit code
0xC000001Don a CPU lacking the build's instruction sets), the built-in CHDSharp encoder takes over automatically and the crash is decoded into plain language with guidance; a startup check warns when the bundled chdman cannot run. Startup logs record the process and OS architectures and which tool binary was selected. -
Safe deletion — source files (and dependencies such as
.bin,.sub) are only deleted after confirmed success, and a dependency a descriptor points at outside the selected input folder is kept and reported rather than deleted. - Batch verification — checksums and structural integrity of existing CHD files via CHDSharp.
- Optional checksum report — whole-image SHA-1, CRC-32 and XXH3 hashes plus per-track hashes for CD/GD-ROM images, written next to each verified CHD.
-
Automated organization — optionally move verified/failed files into
Success/Failedsubfolders; these folders are excluded from subsequent scans. - Empty-folder cleanup — empty subdirectories are removed after files are moved or deleted.
-
Dependency check at startup — on Windows the user is notified if
chdman.exeis missing; conversions then run on the always-available built-in CHDSharp encoder, so a batch never refuses to start for a missing encoder. - File-system monitoring — the input folder is watched during batch processing to explain why a file went missing mid-operation.
- Corrupt-image early warning — ISO sizes that don't match any standard sector layout are flagged before conversion.
- Resilient file operations — deletions and moves retry with backoff (~45 s) against transient locks (antivirus, indexer) and clear read-only attributes when needed.
- Real-time telemetry — disk write/read speeds and elapsed time during operations.
- Read-ahead extraction — CHDSharp pre-decompresses the next 16 hunks in the background while extracting, so sequential reads overlap the writes.
- High-performance logging — Serilog with a batched UI log capped at 50,000 characters, so a large log cannot freeze the window.
- Avalonia Fluent theming — dark theme with a static dark background and rounded corners on Windows, Linux and macOS.
- Automatic update checks — GitHub releases are checked at startup; the user is offered the download page.
- Automated bug reporting — warning-and-above log events are forwarded to the PureLogicCode BugReport API (see Bug Reporting System).
| Category | Formats |
|---|---|
| Standard images |
.iso, .cue (+.bin), .img, .ccd (+.img), .raw, .toc, bare .bin
|
| Console-specific |
.gdi (Dreamcast), .pbp (PlayStation) |
| Compressed |
.cso (Compressed ISO), .isz (UltraISO), .ecm (Error Code Modeler) |
| Alcohol 120% |
.mds (+.mdf), including 2448-byte subchannel sectors |
| Laserdisc |
.avi (A/V CHD input/output via createld/extractld) |
| Split sets |
.001/.002…, .i00/.i01… (add the first volume; the rest are found) |
| Archives |
.zip, .7z, .rar
|
| Output | .chd |
The full input set is defined in FileExtensions.AllSupportedInputExtensionsForConversion: .cue, .iso, .img, .gdi, .toc, .raw, .ccd, .bin, .mds, .ecm, .isz, .avi, .001, .i00, .zip, .7z, .rar, .cso, .pbp. All extension checks are case-insensitive.
Only the descriptor or first volume of a multi-file set is listed for conversion: the .mdf behind a .mds, the .bin behind a .cue, and the later parts of a split set are found automatically, so each disc converts once. Every format above is handled in-process — the built-in CHDSharp encoder, plus the bundled chdman (Windows) and 7-Zip (7za on Windows, 7zz on Linux/macOS), are all that ship; there is nothing else to install, and x64 and ARM64 get the same feature set.
Content is inspected first; the extension only decides the outcome for files whose content did not settle it.
-
Content inspection — the leading bytes are read. A raw CD image, an Alcohol descriptor, an ISZ, an ECM, an archive or an existing CHD is routed on what it is, whatever it is called. A raw CD image gets a generated cue and goes to
createcd. - Split volume sets — numbered pieces are rejoined into one image, which is then classified as above.
-
Compressed containers —
.isz,.ecmand.csoare decompressed in-process and the restored image is classified as above. -
Descriptors —
.cue/.gdi/.toc→createcdafter cue normalization..ccdbecomes a cue via CCDSharp,.mdsvia the Alcohol parser,.pbpis extracted to CUE/BIN via PBPSharp. -
.iso(DVD images) →createdvd, once content inspection has ruled out a mislabelled raw CD dump -
.img(hard disk images) →createhd, unless an accompanying.cueexists →createcd -
.raw(raw data) →createraw(with an explicit unit size-us 2352). Cue descriptors referencing.rawaudio tracks convert through the cue, whose track types already carry the 2352-byte unit size (createcdrejects-us). -
.avi(laserdisc) →createld(A/Vavhucodec, one frame per hunk), always, regardless of the Force CD/DVD checkboxes.
The user can override 5–7 via Force CD / Force DVD checkboxes. PBP always extracts first.
Generated cue sheets reference the disc image where it already lies rather than copying it, because chdman resolves a cue's FILE entry against the cue's own directory. That also means such a cue must be written on the same volume as the image: chdman joins the FILE string to the cue's directory unconditionally, so an absolute path becomes C:\temp\D:\game.iso and fails.
- Migrated from external
chdman-based verification to the pure C# CHDSharp library. - Replaced
maxcsoandpsxpackagerexecutables with the in-house CSOSharp and PBPSharp libraries. - Added CloneCD support via CCDSharp.
- Introduced CUE normalization, MP3 decoding, archive dependency validation, and a file watcher for missing-file diagnostics.
- Added content-based format detection, so inputs are routed by their leading bytes rather than their extension.
- Added Alcohol 120% (
.mds/.mdf), split volume sets, in-process ISZ decompression and in-process ECM decoding, removing the last external-tool dependency. - Made conversion output non-destructive by staging to
.chdtmpand moving into place only on success. - Added raw-audio-track detection in cue files;
-us 2352is applied tocreaterawand cue descriptors are converted through their cue (which carries the unit size in its track types). - Added retry logic to CloneCD bin-file copies and overflow-safe arithmetic in PBP TOC parsing.
- Normalised endianness across CSO/PBP parsers (replaced endianness-dependent
BitConverterwith explicitBinaryPrimitives.ReadUInt32LittleEndian).
Start here
Using the app
How it works
Reference