How to Make Your Own DSD Files from FLACs

Discussion in 'Computer Audiophile: Software, Configs, Tools' started by ohshitgorillas, Nov 12, 2023.

Tags:
  1. ohshitgorillas

    ohshitgorillas Friend

    Pyrate
    Joined:
    Nov 27, 2015
    Likes Received:
    685
    Trophy Points:
    93
    Location:
    Sacramento, CA
    What?
    A brief introduction for newbies: What is DSD and how can upsampling the same file possibly make it sound better? In your DAC, the signal is oversampled by something like 8-200x and, in D/S DACs, it's stripped down to 1-bit before being converted to an analog signal. These oversampling filters aren't perfect and each one makes compromises in some area to achieve superiority in another. Your DAC does a decent job of oversampling, but a PC can do better: more processing power = fewer compromises. DSD files are already 1-bit with sampling rates of at least 2.8224 MHz (= 44100 Hz x 64), so they skip the oversampling filter and are fed directly to the DAC, hence the name "Direct Stream Digital".

    How do they sound? More natural, coherent, and dynamic, with improved separation and micro-detail retrieval. Instruments sound more textured and like the real versions of themselves, chaotic passages maintain coherence and separation. In two words, they are cleaner and clearer than the original PCM files (YMMV depending on the DAC and its DSD/PCM implementations).


    ----------------------------------------------------------------------------------------------------------------------------------------------------------

    Why?
    My original interest in this was sparked by the HQPlayer vs SoX thread, in which @Garns managed to hack SoX to allow the use millions of taps in its upsampling filters. I made a handful of upsampled albums which sounded pretty good, and I also stumbled across a SoX fork capable of converting PCM files to DSD.

    This isn't news, by the way--this SoX fork is several years old, but it took me a lot of effort to get it working, so I figured an easy-to-follow guide was in order.


    ----------------------------------------------------------------------------------------------------------------------------------------------------------

    How?

    INSTALLATION
    Now, let's get into the nuts and bolts. For this, you'll need a Linux machine, as I'm not sure how to do this on Windows. Sorry, non-nerds.

    First, install libflac as well as the libs for any other formats you might want to convert.

    Next, clone and install the forked SoX from the github repo mansr/sox:

    Code:
    git clone https://github.com/mansr/sox
    cd sox
    autoreconf -i
    ./configure
    make
    sudo make install
    BASIC USAGE
    Here is the entry in the man page for the SDM add-on to sox:

    Code:
           sdm [-f filter] [-t order] [-n num] [-l latency]
                  Apply a 1-bit sigma-delta modulator producing DSD output.  The input should be previously upsampled, e.g. with the rate effect, to a high rate, 2.8224MHz for DSD64.  The -f option selects the noise-shaping filter from the following list where the number indicates the order of the filter:
                     clans-4      sdm-4
                     clans-5      sdm-5
                     clans-6      sdm-6
                     clans-7      sdm-7
                     clans-8      sdm-8
    
                  The noise filter may be combined with a partial trellis/viterbi search by supplying the following options:
    
                  -t     Trellis order, max 32.
    
                  -n     Number of paths to consider, max 32.
    
                  -l     Output latency, max 2048.
    
                  The result of using these parameters is hard to predict and can include high noise levels or instability.  Caution is advised.
    Although the man page entry says the file needs to be previously upsampled, this is actually misleading (and difficult, if you saw the previous iteration of this guide where I tried this) as the upsampling is done automatically when running the command:

    Code:
    sox input.flac output.dsf rate 2822400
    If you get clipping warnings, you can lower the volume:

    Code:
    sox input.flac output.dsf vol -0.5dB rate 2822400
    You can also specify the noise-shaping filter. I use CLANS-8:

    Code:
    sox input.flac output.dsf rate 2822400 sdm -f clans-8
    Additionally, you can specify the trellis order and number of trellis paths. Perhaps someone with more knowledge about these things would care to explain them, but it's easy enough to max out the settings if you have a powerful PC:

    Code:
    sox input.flac output.dsf rate 2822400 sdm -f clans-8 -t 32 -n 32
    Note that using -t tends to yield "failed to converge" warnings as well as take an extremely long time to process (hours per song on an i7-11700KF). I am currently experimenting with lowering the trellis order until these warnings disappear, however, this is a time-consuming exercise and may vary with the files themselves. A good value seems to be 24.

    Last but not least, this SoX fork supports up to DSD256, however, I got bad popping noises on tracks that I upsampled to DSD256 without specifying the trellis order and number of paths. That being said, DSD64 is enough to defeat the internal oversampling filter of a D/S DAC and, based on my listening, adding extra samples doesn't seem to improve anything. YMMV.

    ----------------------------------------------------------------------------------------------------------------------------------------------------------

    AUTOMATION
    This is all well and good if you just want a few test tracks, but if you want to do a whole album, you'll need some automation. Below is a bash script that will loop over all FLAC files in the present working directory and convert them to DSF. It also has an automated volume reduction algorithm: if any clipping is detected on any track, the script reduces the volume by -0.5dB and restarts with the first track. This can take a while with badly clipped recordings, but ultimately ensures that all songs and samples in the album maintain the same relative volume.


    Code:
    #!/bin/bash
    # flac2dsf64.sh
    # convert all FLAC files in the current directory to DSF
    # Function to process a file to DSF
    process_file() {
        input_file="$1"
        output_file="${input_file%.flac}.dsf"
        volume="$2"
    
        # Process file to DSF
        sox_command="sox -V3 \"$input_file\" \"$output_file\" vol ${volume}dB rate 2822400 sdm -f clans-8"
        echo "Processing: $sox_command"
     
        # Run sox command and capture stdout
        output=$(eval "$sox_command" 2>&1)
        echo "$output"
    
        # Check for clipping in the output
        if grep -qi "clipped" <<< "$output"; then
            # Clipping detected, decrease volume by -0.5 and set restart flag
            volume=$(echo "$volume - 0.5" | bc)
            echo "Clipping detected in $input_file. Decreasing volume to ${volume}dB and restarting..."
            restart_required=true
        else
            restart_required=false
        fi
    }
    
    # Initial volume
    volume=0
    
    # Loop until no clipping is detected
    while true; do
        restart_required=false
    
        # Loop over each FLAC file in the current directory
        for flac_file in *.flac; do
            process_file "$flac_file" "$volume"
    
            # Exit the loop if restart is required
            if "$restart_required"; then
                break
            fi
        done
    
        # Exit the loop if no restart is required
        if ! "$restart_required"; then
            break
        fi
    done
    
    
    That's it! Happy listening and let us know how you think they sound.
     
    • Epic Epic x 3
    • Like Like x 1
    • List
    Last edited: Nov 16, 2023
  2. ohshitgorillas

    ohshitgorillas Friend

    Pyrate
    Joined:
    Nov 27, 2015
    Likes Received:
    685
    Trophy Points:
    93
    Location:
    Sacramento, CA
    Well, naturally, as soon as I post this I figure out I'm doing something wrong. The file needs to be pre-upsampled to at least 2822400 Hz (DSD64) before doing the conversion. I'll do some experimenting with this and update my guide accordingly. I will make a note on this post when those edits are finished.

    EDIT: I've got it figured out, I just need to polish the automation scripts off now and figure out an ideal trellis order to avoid 'failed to converge' warnings.

    EDIT; updated the Basic Usage section, still testing code

    EDIT; what a brutal journey... but it's finished and it works. enjoy!

    EDIT: jesus tittyfucking christ, it turns out my first approach was right all along and the files didn't need to be pre-upsampled. what a shitshow. in either case, I've updated the guide without the unnecessary intermediate step of converting to w64. this is the final version.
     
    • heart heart x 2
    • Like Like x 1
    • List
    Last edited: Nov 16, 2023

Share This Page