High Definition Compatible Digital: Difference between revisions
(→Decoding software: +hdcd.exe and authors info) |
Porcuswiki (talk | contribs) m (Wayback Machine link) |
||
(44 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
{|class="wikitable" width="100%" | |||
! <big>TL;DR version:</big> | |||
| [[#HDCD was (mostly) a scam|HDCD was (mostly) a scam]], but thousands of popular CDs released from 1995-present have this encoding. ([[List of HDCD-encoded Compact Discs]]) | |||
'''Do not batch-convert your lossless audio to 24-bit.''' Leave your lossless CD rips 16-bit and use an audio player capable of decoding HDCD, like [[Foobar2000]]. | |||
|} | |||
'''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. —[https://en.wikipedia.org/wiki/High_Definition_Compatible_Digital HDCD article at Wikipedia] | '''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. —[https://en.wikipedia.org/wiki/High_Definition_Compatible_Digital 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. | 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 | 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 [http://www.head-fi.org/t/65414/hdcd-list list of known HDCD compact discs] at Head-Fi.org | ||
== Function and features == | == 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. | 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. | ;Peak extend (PE): 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. | ;Low-level gain adjustment (LLE): 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|§Regarding the Low-level Gain Adjustment feature]]. | ||
;Filters:There | ;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. | 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: [http://www.audiomisc.co.uk/HFN/HDCD/Enigma.html Page 1] [http://www.audiomisc.co.uk/HFN/HDCD/Examined.html Page 2] | * See a full technical examination by Jim Lesurf: [http://www.audiomisc.co.uk/HFN/HDCD/Enigma.html Page 1] [http://www.audiomisc.co.uk/HFN/HDCD/Examined.html Page 2] | ||
== Audio Formats == | |||
The Model Two supported all CD-Audio and DVD-Audio formats. Sample rates of 44100, 88200, 176400, 48000, 96000, or 192000 Hz, and bit depths of 16, 20, or 24 bits. HDCD packets may appear in any PCM that passed through a Model Two. | |||
== Decoding software == | == 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. [http://forum.doom9.org/showthread.php?t=129136] 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. | 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. [http://forum.doom9.org/showthread.php?t=129136] 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). | 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 may be slight variations in the output of the different tools. | ||
=== Audio players === | === Audio players === | ||
Line 26: | Line 35: | ||
* [[dBpoweramp]] will decode HDCD to 24-bit PCM (uses the hdcd.exe tool for processing) | * [[dBpoweramp]] will decode HDCD to 24-bit PCM (uses the hdcd.exe tool for processing) | ||
* [[CUETools]] | * [[CUETools]] | ||
* [https://www.jriver.com/index.html JRiver Media Center] | |||
=== hdcd.exe === | === 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. | 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 | hdcd.exe -o OUT24.wav HDCD16.wav | ||
=== libhdcd === | |||
An open-source HDCD decoder library exists as [https://github.com/bp0/libhdcd libhdcd]. It is based on the foo_hdcd and ffmpeg/af_hdcd work by Christopher Key, Chris Moeller (kode54), Gumboot, Burt P. and others. | |||
It comes with a detection/decoder tool: | |||
hdcd-detect -o OUT24.wav HDCD16.wav | |||
If an output file is not specified, only HDCD detection information is printed. | |||
=== FFmpeg === | === 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. | 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 | '''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 [http://git.videolan.org/?p=ffmpeg.git;a=commit;h=ba69a81019a2642969b108c39e3bea7d2f8ffbfa this commit]. | ||
;Example:FLAC with HDCD encoded in 16-bit (perhaps ripped from a CD) | ;Example:FLAC with HDCD encoded in 16-bit (perhaps ripped from a CD) | ||
Line 42: | Line 59: | ||
;Example 3:... if you want to use another format (like pcm_s24le), you have to specify it with the acodec option | ;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 | ffmpeg -i input16.wav -af hdcd -acodec pcm_s24le output24.wav | ||
* See [https://ffmpeg.org/ffmpeg-filters.html#hdcd FFmpeg → filters → hdcd] | |||
==== Conversion to AAC ==== | |||
If using the FFmpeg to convert HDCD-encoded lossless to AAC, it is important to note that the [[Fraunhofer FDK AAC|Fraunhofer FDK AAC (libfdk-aac) encoder]] only allows 16-bit PCM input, so FFmpeg will convert the 32-bit PCM output of the filter back to 16-bit before encoding AAC. The [[Libavcodec AAC|FFmpeg 3.0+ AAC encoder]] uses floating-point input, so the 32-bit PCM output of the filter will be converted to floating point PCM before encoding AAC. In this case, the native AAC encoder is preferable to FDK AAC, but only if using CBR, and at a high enough bitrate to overcome the other deficiencies of the libavcodec AAC encoder. | |||
==== Analyze mode ==== | |||
[[File:Ffmpeg-hdcd-analyze.png|right|200px|An example of analyze_mode.]] | |||
FFmpeg's HDCD filter has a mode, selected by filter option, to aid in analysis of HDCD encoded audio. | |||
In this mode the audio is replaced by a solid tone and the amplitude is adjusted to signal some specified aspect of the process. | |||
The output file can be loaded in an audio editor alongside the original, where the user can see where different features or states are present. | |||
An example track, Neil Young - Red Sun, from Silver & Gold. The different outputs loaded together in Audacity shown to the right are explained below. | |||
{| class="wikitable" | |||
! Track | |||
! Option setting | |||
! hdcd-detect option | |||
! Description | |||
|- | |||
| 1 || analyze_mode=off || -z off || HDCD decoded | |||
|- | |||
| 2 || analyze_mode=lle || -z lle || LLE gain adjust levels in each sample | |||
|- | |||
| 3 || analyze_mode=pe || -z pe || Samples where PE occurs | |||
|- | |||
| 4 || analyze_mode=pe:force_pe=true || -z pel || Original sample was in the -3dBFS range (should match above when PE is permanent, but maybe not when it isn't) | |||
|- | |||
| 5 || analyze_mode=tgm || -z tgm || Samples where the target_gain was ignored because it didn't match in both channels | |||
|- | |||
| Not shown || analyze_mode=cdt || -z cdt || Samples where HDCD decoding was active (whole track in this case) | |||
|- | |||
| Not shown || analyze_mode=lle:process_stereo=false || -z ltgm || Similar to tgm, but shows the level at each sample in each channel | |||
|} | |||
==== 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>) or using something like a [https://ffmpeg.zeranoe.com/builds/ Zeranoe FFmpeg build for Windows]. | |||
;hdcdscan.sh: | |||
<pre> | |||
#!/bin/bash | |||
# A bash script for scanning for files with HDCD encoding. | |||
# Burt P. | |||
# | |||
# Usage: | |||
# ./hdcdscan.sh *.flac | |||
# or | |||
# find /some/archive/path/ -name '*.flac' -exec ./hdcdscan.sh {} \; | |||
# or | |||
# find /some/archive/path/ -name '*.flac' -print0 |xargs -0 -P 4 -n 1 ./hdcdscan.sh | |||
# or (prolly best) | |||
# find /some/archive/path/ -name '*.flac' -print0 |xargs -0 -P 1 -n 50 ./hdcdscan.sh | |||
# | |||
#FFMPEG="/home/you/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 | |||
CHECK_MODES="" # use both modes and see if md5 matches | |||
#---- | |||
CPU_COUNT=$(grep -c ^processor /proc/cpuinfo) | |||
#CPU_COUNT=4 # manual | |||
if [ -z "$FFMPEG" ]; then | |||
FFMPEG=$(which ffmpeg) | |||
fi | |||
FILTERCHK=$("$FFMPEG" -filters 2>&1 | grep hdcd) | |||
if [ -z "$FILTERCHK" ]; then | |||
echo "$FFMPEG is not built with hdcd filter support" | |||
exit 1 | |||
fi | |||
#FORMATSTR="-acodec pcm_s24le -f wav" # if using wav temp file | |||
FORMATSTR="-f s24le" # if using /dev/null | |||
scan_file() { | |||
local SF | |||
local TAG | |||
local P_TLIMIT | |||
TAG="$$_$1" | |||
SF="$2" | |||
P_TLIMIT="" | |||
if [ -n "$TLIMIT" ]; then P_TLIMIT="-t $TLIMIT"; fi | |||
if [ -f "$f" ]; then | |||
#TF="$TDER/hdcdout_$TAG.wav" | |||
TF="/dev/null" | |||
TFO="$TDER/hdcdout_$TAG.ffmpeg-out" | |||
echo "$f ..." >"$TFO" | |||
"$FFMPEG" -hide_banner -nostats -y -v verbose -i "$f" $P_TLIMIT -vn -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 "$DETECTED" ]; then | |||
if [ -n "$CHECK_MODES" ]; then | |||
SUM1=$("$FFMPEG" -y -v verbose -i "$f" $P_TLIMIT -vn -af hdcd=process_stereo=0 $FORMATSTR md5: 2>/dev/null) | |||
SUM2=$("$FFMPEG" -y -v verbose -i "$f" $P_TLIMIT -vn -af hdcd=process_stereo=1 $FORMATSTR md5: 2>/dev/null) | |||
if [ "$SUM1" == "$SUM2" ]; then | |||
echo "md5 sums match: $SUM1" >>"$TFO" | |||
else | |||
echo "md5 sums differ: ps0: $SUM1, ps1: $SUM2" >>"$TFO" | |||
fi | |||
fi | |||
fi | |||
sed -i -e "s#^\[Parsed_hdcd_[0-9]\+ @ [0-9a-fx]\+\] ##" "$TFO" | |||
sed -i -e "s#^#[$TAG] #" "$TFO" | |||
if [ -n "$SIMPLE" ]; then | |||
head -n 1 "$TFO" | |||
if [ -n "$CHECK_MODES" ]; then grep "md5 sums " "$TFO"; fi | |||
grep "HDCD detected:" "$TFO" | |||
else | |||
cat "$TFO" | |||
fi | |||
if [ -f "$TFO" ]; then rm "$TFO"; fi | |||
if [ -f "$TF" ]; then rm "$TF"; fi | |||
fi | |||
} | |||
NN=0 | |||
for f in "$@" | |||
do | |||
scan_file "$NN" "$f" & | |||
while [ $(jobs -r| wc -l) -ge "$CPU_COUNT" ] ; do sleep 0.2 ; done | |||
((NN++)) | |||
done | |||
wait | |||
</pre> | |||
== HDCD never caught on == | |||
For casual readers, here is what you need to know about the existence of HDCD. | |||
* HDCD was invented by a company call Pacific Microsonic (PM) that made audio equipment designed for use in studios. | |||
* Only PM equipment could encode HDCD, and only PM-licensed consumer equipment could decode it. | |||
* It was claimed that it was compatible with standard CD audio, which was only true in the encoding/decoding sense, and not so much in the audible sense. | |||
* The information about how it worked was mostly kept secret to keep others from using it, and the information that was made public was intentionally vague. | |||
* Many studios used PM equipment even if they didn't know it, or their engineers didn't know how to use it. | |||
* Because of this, thousands of releases have HDCD encoding. See [[List of HDCD-encoded Compact Discs]]. | |||
* Much of the time, the engineers turned all HDCD features off, but the HDCD control packets were still inserted into the discs anyway. For these discs, there is absolutely no benefit in decoding HDCD. | |||
* Many times, mastering engineers who didn't know how to use the HDCD features caused absurd HDCD discs to be released, like "For the Masses" (1998), and unintentional "Special Mode" discs. | |||
* Of the three "features" of HDCD, in the vast majority of cases only one is useful or even worth decoding: PE. | |||
* Microsoft bought PM for the IP part of the business, that is, to collect royalties from HDCD without developing it or contributing to it in any way. | |||
* HDCD is now dead, except for all the existing PM studio equipment that is still producing zombie HDCD discs (or tracks), even with all the features turned off. | |||
== Technical notes == | |||
=== Packet formats === | |||
pe = peak extend (PE), tg = target gain (LLE), tf = transient filter | |||
;Packet format ''A'': 8-bit code, tg is a 3-bit value (-7.0dB to 0.0dB steps of 1dB). This {{discogs|3192807|HDCD Sampler (1992)}} is an example of a disc with this packet type. | |||
{| class="wikitable" | |||
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 | |||
|- | |||
| 0 || 0 || tf || pe || 0 ||colspan=3|tg | |||
|} | |||
;Packet format ''B'': 16-bit (8-bit code, 8-bit XOR of code), tg is a 4-bit value used as a 3.1 fixed-point number (-7.5dB to 0.0dB steps of 0.5dB). Most discs after 1995 use this packet type. | |||
{| class="wikitable" | |||
| 15 || 14 || 13 || 12 || 11 || 10 || 9 || 8 || || 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 | |||
|- | |||
| 0 || 0 || tf || pe ||colspan=4|tg || ||colspan=8| XOR check | |||
|} | |||
''A'' and ''B'' are unofficial names of the different formats based on counters in the FFmpeg HDCD filter source code. If using -v verbose with the filter, Counter A, B, C will be reported. A is the number of 8-bit format packets, B is the number of 16-bit format packets validated, C is total packets. almost_A is the number of packets that were supposed to be an A format, but one of the expected zeros was a one. checkfail_B is the number of packets that failed the XOR check for B format. In a perfect HDCD encoding A+B=C, likely as A+0=C or 0+B=C. | |||
== 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" [https://hydrogenaud.io/index.php/topic,79427.msg900371.html#msg900371] paper:[https://web.archive.org/web/20150520174117/https://www.goodwinshighend.com/music/hdcd/aes_paper.pdf] | |||
===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" | |||
If you see a level of greater than 4.0 of gain adjustment, there was an error made in the disc where the mastering engineer mistakenly used "Special Mode". This is not only wrong, but there is no consumer equipment that can even decode this level of gain adjustment! Only by playing this back through the PM Model One (44 and 48 kHz only) or the PM Model Two (added dual- and quad-rate sampling rates) could this file be properly decoded | |||
:— Charles Hansen [http://www.head-fi.org/t/65414/hdcd-list/570#post_12725140] | |||
===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 [http://www.head-fi.org/t/65414/hdcd-list/570#post_12725140] | |||
:— US Patent Number 5,388,221: [https://patents.google.com/patent/US5388221A] | |||
===HA Forum posts of interest=== | |||
* [https://hydrogenaud.io/index.php/topic,30999.msg513734.html#msg513734 Christopher Key - 31 August, 2007, 04:52:24 PM] | |||
* [https://hydrogenaud.io/index.php/topic,30999.msg778594.html#msg778594 Gumboot - 11 December, 2011, 05:41:43 PM], re: gain change ramp | |||
* [https://hydrogenaud.io/index.php/topic,30999.msg778685.html#msg778685 Gumboot - 12 December, 2011, 12:21:01 PM], re: nearly stateless | |||
==See also== | |||
* [[foobar2000:HDCD decoder (foo_hdcd)|HDCD decoder (foo_hdcd)]], a foobar2000 component | |||
==External links== | |||
* [https://web.archive.org/web/20150520174117/https://www.goodwinshighend.com/music/hdcd/aes_paper.pdf Compatible Resolution Enhancement in Digital Audio Systems], a paper presented to AES Convention 1996 by Keith Johnson | |||
* {{ha|https://hydrogenaud.io/index.php/topic,79427.msg737725.html#msg737725|Charles Hansen describes HDCD}} |
Latest revision as of 04:30, 31 August 2024
TL;DR version: | HDCD was (mostly) a scam, but thousands of popular CDs released from 1995-present have this encoding. (List of HDCD-encoded Compact Discs)
Do not batch-convert your lossless audio to 24-bit. Leave your lossless CD rips 16-bit and use an audio player capable of decoding HDCD, like Foobar2000. |
---|
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 (PE)
- 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 (LLE)
- 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.
Audio Formats
The Model Two supported all CD-Audio and DVD-Audio formats. Sample rates of 44100, 88200, 176400, 48000, 96000, or 192000 Hz, and bit depths of 16, 20, or 24 bits. HDCD packets may appear in any PCM that passed through a Model Two.
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 may be 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
- JRiver Media Center
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
libhdcd
An open-source HDCD decoder library exists as libhdcd. It is based on the foo_hdcd and ffmpeg/af_hdcd work by Christopher Key, Chris Moeller (kode54), Gumboot, Burt P. and others.
It comes with a detection/decoder tool:
hdcd-detect -o OUT24.wav HDCD16.wav
If an output file is not specified, only HDCD detection information is printed.
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
Conversion to AAC
If using the FFmpeg to convert HDCD-encoded lossless to AAC, it is important to note that the Fraunhofer FDK AAC (libfdk-aac) encoder only allows 16-bit PCM input, so FFmpeg will convert the 32-bit PCM output of the filter back to 16-bit before encoding AAC. The FFmpeg 3.0+ AAC encoder uses floating-point input, so the 32-bit PCM output of the filter will be converted to floating point PCM before encoding AAC. In this case, the native AAC encoder is preferable to FDK AAC, but only if using CBR, and at a high enough bitrate to overcome the other deficiencies of the libavcodec AAC encoder.
Analyze mode
FFmpeg's HDCD filter has a mode, selected by filter option, to aid in analysis of HDCD encoded audio. In this mode the audio is replaced by a solid tone and the amplitude is adjusted to signal some specified aspect of the process. The output file can be loaded in an audio editor alongside the original, where the user can see where different features or states are present.
An example track, Neil Young - Red Sun, from Silver & Gold. The different outputs loaded together in Audacity shown to the right are explained below.
Track | Option setting | hdcd-detect option | Description |
---|---|---|---|
1 | analyze_mode=off | -z off | HDCD decoded |
2 | analyze_mode=lle | -z lle | LLE gain adjust levels in each sample |
3 | analyze_mode=pe | -z pe | Samples where PE occurs |
4 | analyze_mode=pe:force_pe=true | -z pel | Original sample was in the -3dBFS range (should match above when PE is permanent, but maybe not when it isn't) |
5 | analyze_mode=tgm | -z tgm | Samples where the target_gain was ignored because it didn't match in both channels |
Not shown | analyze_mode=cdt | -z cdt | Samples where HDCD decoding was active (whole track in this case) |
Not shown | analyze_mode=lle:process_stereo=false | -z ltgm | Similar to tgm, but shows the level at each sample in each channel |
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) or using something like a Zeranoe FFmpeg build for Windows.
- hdcdscan.sh
#!/bin/bash # A bash script for scanning for files with HDCD encoding. # Burt P. # # Usage: # ./hdcdscan.sh *.flac # or # find /some/archive/path/ -name '*.flac' -exec ./hdcdscan.sh {} \; # or # find /some/archive/path/ -name '*.flac' -print0 |xargs -0 -P 4 -n 1 ./hdcdscan.sh # or (prolly best) # find /some/archive/path/ -name '*.flac' -print0 |xargs -0 -P 1 -n 50 ./hdcdscan.sh # #FFMPEG="/home/you/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 CHECK_MODES="" # use both modes and see if md5 matches #---- CPU_COUNT=$(grep -c ^processor /proc/cpuinfo) #CPU_COUNT=4 # manual if [ -z "$FFMPEG" ]; then FFMPEG=$(which ffmpeg) fi FILTERCHK=$("$FFMPEG" -filters 2>&1 | grep hdcd) if [ -z "$FILTERCHK" ]; then echo "$FFMPEG is not built with hdcd filter support" exit 1 fi #FORMATSTR="-acodec pcm_s24le -f wav" # if using wav temp file FORMATSTR="-f s24le" # if using /dev/null scan_file() { local SF local TAG local P_TLIMIT TAG="$$_$1" SF="$2" P_TLIMIT="" if [ -n "$TLIMIT" ]; then P_TLIMIT="-t $TLIMIT"; fi if [ -f "$f" ]; then #TF="$TDER/hdcdout_$TAG.wav" TF="/dev/null" TFO="$TDER/hdcdout_$TAG.ffmpeg-out" echo "$f ..." >"$TFO" "$FFMPEG" -hide_banner -nostats -y -v verbose -i "$f" $P_TLIMIT -vn -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 "$DETECTED" ]; then if [ -n "$CHECK_MODES" ]; then SUM1=$("$FFMPEG" -y -v verbose -i "$f" $P_TLIMIT -vn -af hdcd=process_stereo=0 $FORMATSTR md5: 2>/dev/null) SUM2=$("$FFMPEG" -y -v verbose -i "$f" $P_TLIMIT -vn -af hdcd=process_stereo=1 $FORMATSTR md5: 2>/dev/null) if [ "$SUM1" == "$SUM2" ]; then echo "md5 sums match: $SUM1" >>"$TFO" else echo "md5 sums differ: ps0: $SUM1, ps1: $SUM2" >>"$TFO" fi fi fi sed -i -e "s#^\[Parsed_hdcd_[0-9]\+ @ [0-9a-fx]\+\] ##" "$TFO" sed -i -e "s#^#[$TAG] #" "$TFO" if [ -n "$SIMPLE" ]; then head -n 1 "$TFO" if [ -n "$CHECK_MODES" ]; then grep "md5 sums " "$TFO"; fi grep "HDCD detected:" "$TFO" else cat "$TFO" fi if [ -f "$TFO" ]; then rm "$TFO"; fi if [ -f "$TF" ]; then rm "$TF"; fi fi } NN=0 for f in "$@" do scan_file "$NN" "$f" & while [ $(jobs -r| wc -l) -ge "$CPU_COUNT" ] ; do sleep 0.2 ; done ((NN++)) done wait
HDCD never caught on
For casual readers, here is what you need to know about the existence of HDCD.
- HDCD was invented by a company call Pacific Microsonic (PM) that made audio equipment designed for use in studios.
- Only PM equipment could encode HDCD, and only PM-licensed consumer equipment could decode it.
- It was claimed that it was compatible with standard CD audio, which was only true in the encoding/decoding sense, and not so much in the audible sense.
- The information about how it worked was mostly kept secret to keep others from using it, and the information that was made public was intentionally vague.
- Many studios used PM equipment even if they didn't know it, or their engineers didn't know how to use it.
- Because of this, thousands of releases have HDCD encoding. See List of HDCD-encoded Compact Discs.
- Much of the time, the engineers turned all HDCD features off, but the HDCD control packets were still inserted into the discs anyway. For these discs, there is absolutely no benefit in decoding HDCD.
- Many times, mastering engineers who didn't know how to use the HDCD features caused absurd HDCD discs to be released, like "For the Masses" (1998), and unintentional "Special Mode" discs.
- Of the three "features" of HDCD, in the vast majority of cases only one is useful or even worth decoding: PE.
- Microsoft bought PM for the IP part of the business, that is, to collect royalties from HDCD without developing it or contributing to it in any way.
- HDCD is now dead, except for all the existing PM studio equipment that is still producing zombie HDCD discs (or tracks), even with all the features turned off.
Technical notes
Packet formats
pe = peak extend (PE), tg = target gain (LLE), tf = transient filter
- Packet format A
- 8-bit code, tg is a 3-bit value (-7.0dB to 0.0dB steps of 1dB). This HDCD Sampler (1992) is an example of a disc with this packet type.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | tf | pe | 0 | tg |
- Packet format B
- 16-bit (8-bit code, 8-bit XOR of code), tg is a 4-bit value used as a 3.1 fixed-point number (-7.5dB to 0.0dB steps of 0.5dB). Most discs after 1995 use this packet type.
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0 | 0 | tf | pe | tg | XOR check |
A and B are unofficial names of the different formats based on counters in the FFmpeg HDCD filter source code. If using -v verbose with the filter, Counter A, B, C will be reported. A is the number of 8-bit format packets, B is the number of 16-bit format packets validated, C is total packets. almost_A is the number of packets that were supposed to be an A format, but one of the expected zeros was a one. checkfail_B is the number of packets that failed the XOR check for B format. In a perfect HDCD encoding A+B=C, likely as A+0=C or 0+B=C.
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.
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"
If you see a level of greater than 4.0 of gain adjustment, there was an error made in the disc where the mastering engineer mistakenly used "Special Mode". This is not only wrong, but there is no consumer equipment that can even decode this level of gain adjustment! Only by playing this back through the PM Model One (44 and 48 kHz only) or the PM Model Two (added dual- and quad-rate sampling rates) could this file be properly decoded
- — Charles Hansen [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).
HA Forum posts of interest
- Christopher Key - 31 August, 2007, 04:52:24 PM
- Gumboot - 11 December, 2011, 05:41:43 PM, re: gain change ramp
- Gumboot - 12 December, 2011, 12:21:01 PM, re: nearly stateless
See also
- HDCD decoder (foo_hdcd), a foobar2000 component
External links
- Compatible Resolution Enhancement in Digital Audio Systems, a paper presented to AES Convention 1996 by Keith Johnson
- Charles Hansen describes HDCD on hydrogenaudio