Menu

#232 Add DSD Disc ISO support — direct UDF filesystem readerAdd DSD Disc ISO support — direct UDF filesystem reader

2.0.x
open
None
1
9 hours ago
21 hours ago
Anonymous
No

Hi Maxim,

I've implemented DSD Disc ISO direct reading support for foo_input_sacd,
and I'd like to contribute it to the upstream project.

DSD Disc is a disc image format for publishing DSD audio on recordable
media, standardized by Sony. Unlike SACD ISOs (which use a proprietary
filesystem with SACDMTOC), DSD Disc stores individual DSF files inside
a standard UDF 1.02 volume — the same filesystem used by DVD-Video and
BDMV. Current versions of foo_input_sacd reject these ISOs because
they lack the SACDMTOC signature, even though the audio data is
standard DSD64/128/256.

Implementation approach

Rather than requiring an external UDF library (a heavyweight dependency
for a single purpose), I wrote a lightweight UDF 1.02 parser directly
inside the plugin. Two new files under src/foo_input_sacd/:

udsd_reader_dsd_disc.h (254 lines)
udsd_reader_dsd_disc.cpp (797 lines)

The reader inherits from udsd_reader_t and plugs into the existing
dispatch mechanism in udsd_core.cpp, with essentially zero changes to
the existing SACD/DSF/DFF code paths.

How it works

  1. Detection (g_is_dsd_disc): Opens the ISO with filesystem::g_open_read
    (same pattern as g_is_sacd), reads AVDP at LSN 256, walks VDS to find
    LVD/PD, reads FSD, and scans the root directory for a "DSD_DISC"
    subdirectory.

  2. UDF file traversal: Starting from the root File Entry, traverse
    directory entries recursively. Each FID with directory flag set and
    name != "DSD_DISC" enters a subdirectory; FIDs with .dsf extension
    become tracks.

  3. DSF header parsing: For each found file, read_and validate the
    "DSD " magic, fmt chunk (sample rate, channel count, format_id),
    and data chunk offset. The data offset is used by read_frame()
    for streaming DSD audio direct from the ISO.

  4. ID3 tag extraction: If the DSF header's id3_offset field is non-zero,
    parse the ID3v2 tag for TIT2, TPE1, and TALB frames (title, artist,
    album). UTF-16 and UTF-8 with BOM are handled.

  5. Playback: read_frame() computes the byte offset within the ISO for
    the current frame and reads via udsd_media_t::read(). seek() works
    by frame index. Multi-channel DSD (up to 6ch) is supported.

Endianness note

UDF stores all multi-byte fields in little-endian, while DSF/ID3 fields
are big-endian (network byte order). The reader keeps the two worlds
separate: UDF struct members are read directly without swap on x86
(where host order matches LE), and DSF fields use ntoh32/ntoh64 macros
(aliases for hton32/hton64, symmetric on all architectures).

Files modified

  • src/foo_input_sacd/udsd_reader.h
  • Added DSDDISC = 4 to media_type_e enum

  • src/foo_input_sacd/udsd_core.cpp

  • Added #include "udsd_reader_dsd_disc.h"
  • g_is_our_path: checks g_is_dsd_disc() after g_is_sacd() fails
  • open(): reassigns media_type to DSDDISC when g_is_dsd_disc() matches
  • Reader dispatch: creates udsd_reader_dsd_disc_t for DSDDISC type

Files added

  • src/foo_input_sacd/udsd_reader_dsd_disc.h
    254 lines, pure header. Defines:
  • dsd_disc_track_t — per-track metadata (offset, channels, rate, ID3)
  • UDF structures — udf_tag_t, udf_avdp_t, udf_lvd_t, udf_pd_t,
    udf_fsd_t, udf_fe_t, udf_fid_t, udf_short_ad_t, udf_long_ad_t
  • udsd_reader_dsd_disc_t — class declaration (inherits udsd_reader_t)

  • src/foo_input_sacd/udsd_reader_dsd_disc.cpp
    797 lines, full implementation:

  • g_is_dsd_disc() — static detection probe
  • read_sector() / find_avdp() / read_vds() / read_fsd() — UDF walkers
  • traverse_directory() — recursive UDF FID enumeration
  • read_dsf_header() — DSF chunk parser + data offset calculation
  • read_id3_tag() — ID3v2 frame extractor
  • Full udsd_reader_t interface: open/close/select_track/read_frame/
    seek/get_info

To apply

The patch is against the current foo_input_sacd snapshot (based on
sacddecoder-0.9.6 from SourceForge, foobar2000 SDK 2023-08-23). The
new code compiles cleanly and follows the existing coding style
(underscore naming, foobar2000 SDK conventions).

I'm happy to adjust anything — formatting, naming, structural
decisions. Let me know if you prefer a different approach (e.g. a
separate file input module, or a factored UDF mini-library shared
between readers).

Best regards

Aaron Leung/aaronleung@vip.qq.com

1 Attachments

Discussion

  • Maxim V.Anisiutkin

    Maxim V.Anisiutkin - 17 hours ago

    Hi Aaron,

    It would be great to have some Sony DSD Disc ISO file for testing as well. Could you please point me where to download this?

    Sincerely,
    Maxim

     
  • Maxim V.Anisiutkin

    Maxim V.Anisiutkin - 15 hours ago

    Line 693 in patch file:

    • offset += 10 + ((frame_size + 1) & ~1);
      offset is undeclared identifier.
     
  • Anonymous

    Anonymous - 9 hours ago

    tks

     

Anonymous
Anonymous

Add attachments
Cancel





Auth0 Logo