High Definition Compatible Digital: Difference between revisions

From Hydrogenaudio Knowledgebase
(→‎Scanning a FLAC archive for HDCD using FFmpeg: note about building ffmpeg from source)
Line 46: Line 46:


== Scanning a FLAC archive for HDCD using FFmpeg ==
== Scanning a FLAC archive for HDCD using FFmpeg ==
HDCD stats reporting was added after release 3.1.1. So, as of 30 July 2016, this script requires building ffmpeg from git. (<nowiki>git clone git://source.ffmpeg.org/ffmpeg</nowiki>)


;hdcdscan.sh:
;hdcdscan.sh:

Revision as of 17:14, 30 July 2016

High Definition Compatible Digital, or HDCD is a Microsoft proprietary audio encode-decode process that claims to provide increased dynamic range over that of standard Redbook audio CDs, while retaining backward compatibility with existing Compact disc players. —HDCD article at Wikipedia

Decoding the extra information required an HDCD-compatible player or Windows Media Player. There was no public documentation for the process, but it was eventually reverse engineered. Many HDCD-encoded CDs were released from the mid 1990s but started to disappear around 2008. Some CD's with HDCD codes are still appearing, because they were mastered using HDCD equipment, but do not use the core features of HDCD. Microsoft no longer advertises nor supports HDCD.

A lossless copy of CD audio will include the HDCD data. See List of HDCD-encoded Compact Discs, or the more complete, but less detailed list of known HDCD compact discs at Head-Fi.org

Function and features

HDCD encodes a virtual 20 bits of range in a 16-bit stream. Peak extend is worth about one bit of additional range, while Low level gain adjustment is worth about three bits of additional range. HDCD encoding amplifies the audio stream by 6dB to start.

Peak extend
The base 6dB amplification makes the lower levels louder, but the top 9dB is soft-limited, or "squashed", into the top 3dB in the 16-bit stream. When HDCD is being decoded, the top 9dB is reconstructed.
Low-level gain adjustment
The base 6dB amplification can be corrected down during quieter parts via HDCD control codes to restore the original low level. See §Regarding the Low-level Gain Adjustment feature.
Filters
There were to be two selectable playback filters, but the idea was already patented and so it couldn't be used in Pacific Microsonics or other licensed hardware decoders. Software decoders can detect the feature, but none use it.

When playing the HDCD-CD in a regular CD player, a listener may hear the uncorrected distortion at the peaks, and the low-level remains uncorrected from the base 6dB amplification.

  • See a full technical examination by Jim Lesurf: Page 1 Page 2

Decoding software

As HDCD is a proprietary extension owned by Microsoft, Windows Media Player was the only software to support it for a long time. A simple closed-source Windows-only decoding tool, called hdcd.exe, appeared in 2007 on the Doom9 Forum, a product of reverse-engineering Windows Media Player. [1] Since that time, an open source implementation has come to exist based on this work. It supports the peak extend and gain HDCD features, while the transient filter feature is detected but not implemented.

All of the open source decoding is based of the work of Christopher J. Key (original reverse-engineering), Chris Moeller (open implementation), and Gumboot (C-optimization). Benjamin Steffes simplified the code, by using some pre-computed tables, etc., for inclusion in FFmpeg. There are slight variations in the output of the different tools.

Audio players

  • Windows Media Player, but there is a bug where HDCD will not be enabled if the HDCD control signal is not detected near the beginning of a song
  • Foobar2000 can decode HDCD to 20-bit PCM via foo_dsp_hdcd (source)
  • dBpoweramp will decode HDCD to 24-bit PCM (uses the hdcd.exe tool for processing)
  • CUETools

hdcd.exe

The original Windows-only closed source tool posted on the Doom9 forums in 2007, by C.J. Key. It only works on wav.

hdcd.exe -o OUT24.wav HDCD16.wav

FFmpeg

FFmpeg version 3.1's libavfilter supports a HDCD filter that will convert HDCD-encoded audio to PCM at up to 20-bit precision. The filter is based on the Foobar2000 component source code.

Notice: There was a bug in FFmpeg (version 3.1.1 and earlier) that prevented low-level gain adjustment from working. It was fixed in this commit.

Example
FLAC with HDCD encoded in 16-bit (perhaps ripped from a CD)
ffmpeg -i input16.flac -af hdcd output24.flac
Example 2
Notice the output from the filter is truncated down to 16-bit because the wav muxer defaults to pcm_s16le...
ffmpeg -i input16.wav -af hdcd output16.wav
Example 3
... if you want to use another format (like pcm_s24le), you have to specify it with the acodec option
ffmpeg -i input16.wav -af hdcd -acodec pcm_s24le output24.wav

Scanning a FLAC archive for HDCD using FFmpeg

HDCD stats reporting was added after release 3.1.1. So, as of 30 July 2016, this script requires building ffmpeg from git. (git clone git://source.ffmpeg.org/ffmpeg)

hdcdscan.sh
#!/bin/bash

# A bash script for scanning for files with HDCD encoding.
# Usage:
#   ./hdcdscan.sh *.flac
# or
#   find /some/archive/path/ -name '*.flac' -exec ./hdcdscan.sh {} \;

FFMPEG=`which ffmpeg`
#FFMPEG="~/gits/ffmpeg/ffmpeg" # if using ffmpeg from git

TDER="/run/shm" # temp directory
TLIMIT=30       # scan the first N seconds, empty for no limit
SIMPLE="y"      # show only summary, empty for no
ONLY_HDCD="y"   # show only files with hdcd detected, empty for no

FORMATSTR="-f s24le"
#FORMATSTR="-acodec pcm_s24le -f wav"  # alternate

#----

FILTERCHK=$("$FFMPEG" -filters 2>&1 | grep hdcd)
if [ -z "$FILTERCHK" ]; then
    echo "$FFMPEG is not built with hdcd filter support"
    exit 1
fi

NNN=0
for f in "$@"
do
    if [ -f "$f" ]; then
        TF="$TDER/hdcdout_$$_$NNN.wav"
        #TF="/dev/null" # alternate
        TFO="$TDER/hdcdout_$$_$NNN.ffmpeg-out"
        echo "[$NNN] $f ..." >"$TFO"
        P_TLIMIT=""
        if [ -n "$TLIMIT" ]; then
            P_TLIMIT="-t $TLIMIT"
        fi

        "$FFMPEG" -hide_banner -nostats -y -v verbose -i "$f" $P_TLIMIT -af hdcd $FORMATSTR "$TF" 2>&1 | grep "_hdcd_" >>"$TFO"
        DETECTED=$(grep "HDCD detected: yes" "$TFO")
        if [ -n "$ONLY_HDCD" ]; then            
            if [ -z "$DETECTED" ]; then
                echo -n "" >"$TFO"
            fi
        fi
        if [ -n "$SIMPLE" ]; then
            head -n 1 "$TFO"
            grep "HDCD detected:" "$TFO"
        else
            cat "$TFO"
        fi

        if [ -f "$TFO" ]; then rm "$TFO"; fi
        if [ -f "$TF" ]; then rm "$TF"; fi
        ((NNN++))
    fi
done

Interesting Notes

Regarding HDCD detection

The arrival of a valid packet for a channel resets a code detect timer for that channel. If both channels have active timers, then code is deemed to be present and the filter select data is considered valid immediately. However, any command data which would effect the level of the signal must match between the two channels in order to take effect. The primary reason for this is to handle the case where an error on one channel destroys the code. In such a case, the decoder will mistrack for a short time until the next command comes along, which is much less audible than a change in gain on only one channel, causing a shift in balance and lateral image movement. If either of the code detect timers times out, then code is deemed not to be present, and all commands are canceled, returning the decode system to its default state. If the conditions on the encoder side are not changing, then command packets are inserted on a regular basis to keep the code detect timers in the decoder active and to update the decoder if one starts playing a selection in the middle of a continuous recording.

— "extract from the AES paper presented by Keith Johnson" [2] paper:[3]

Regarding the Low-level Gain Adjustment feature

There are two modes of Low Level Extension, “Normal” and “Special”. Normal mode begins to affect the input signal 45 dB below peak level, gradually raising the gain 4 dB as the level drops over an 18 dB range. Special mode begins to affect the input signal 39 dB below peak level, and gradually raises the gain 7.5 dB over a 26 dB range. Normal mode is optimized to provide the best combination of decoded dynamic range and resolution and undecoded compatibility. Special mode is designed to provide the best possible decoded dynamic range and resolution at some potential expense of undecoded compatibility. To access Special mode, from the Operating Menu select (SETUP/OUTPUT/HDCD_16/LOWLVL/ SPECIAL). Typically, Special mode is used only for HDCD 16-bit master tracking with the assumption that the recording will be decoded by the Model Two to a 24-bit or 20-bit word length for digital post production before being re-encoded to HDCD 16-bit using Normal mode to produce a release master.

— "from PM operator's manual" [4]

Regarding the Playback Filters feature

[T]he PM Model One and Model Two professional units, which were combination A/D and D/A converters) that had two different playback (reconstruction) filters for HDCD. While the PM A/D used two different anti-aliasing filters while performing A/D conversion (depending on the level of high-frequency content), they were precluded from using two different playback filters as Ed Meitner had already patented that idea for Museatex (now out of business).

— CHansen [5]

Links