Hi-Res的意义(外一则)

(本文部分观点已经在在各种旧文中发表过,如果有既视感为正常现象。)

Hi-Res音频(相比CD)是否有意义?首先要客观分析HR到底改变了什么。

Remastering / remix

之前提过,很多时候Hi-Res最大的意义并不在于“High”本身,而是给了厂牌一次re-release的机会。这本质上和是否HR是没有任何关系的,唱片公司如果愿意,完全可以发行remastered的CD(事实上,很多精选集CD里的旧曲都进行了remaster)。注意这里的remastering是指狭义的、即混音有明显的变化的情况,从物理角度来说就是波形或频谱有明显的变化,不包括单纯的音量、动态范围变化(compress),那个下面专门叙述。

当然,重新混音并不是单纯的技术问题,而且还有艺术发挥的成分,所以这个主观性就很大了。很多时候可能重混后的版本不如原版(个人喜好)。随便举个例子,Lantis的HR版的『U・N・M・E・I ライブ』和CD版混音有较为明显的区别,HR版声场重新调整过,但是我个人觉得人声偏小,更喜好CD版。另外就是上次说过的「THE IDOLM@STER MILLION THE@TER GENERATION 11 UNION!!」这张碟也有类似区别。

对于新发行的音乐,一般CD版和HR版不会也不应该有混音(狭义)的区别——几乎不存在某波形HR能发挥、CD发挥不出来的情形。如果厂商这么做,那只能认为是为了商业考虑故意劣化CD版,而不是什么技术限制。

高采样率

一般HR都是从CD的44100Hz提升到96000Hz。由于采样定理和人耳的频率听觉极限客观摆在那里,可以自信地说,高采样率应该是HR最无用的提升没有之一。

硬要说的话,有个小问题就是现在音乐大多在制作过程中使用96000Hz(或者48000Hz?),而CD的采样率由于历史原因是44100这个不能整除的数字,所以resample可能会有时域上的aliasing等问题。不过,有大量高质量的resampling算法的存在,这个问题在主观听感上的影响可以忽略不计。

高量化精度

CD的量化精度(位深)是16bit,HR一般提升到24bit或者32bit。虽然从听感上来说这个到底能否能产生肉耳可辨的区别也很难讲,但是考虑到类比图像的话,8bit/channel这个在当年被普遍认为绰绰有余的位深现在肉眼可见的捉襟见肘(更不要提当年为了work around这个位深在深色感知灰度不足的问题,搞出的遗毒万年的gamma空间,这里按下不表),这里我们还是保守点说高位深还是大概有用的。而且高量化精度最大的优点就是给响度/振幅调整留下了足够的空间——这点在下面详述。

动态范围

前面铺垫了这么多,重头戏其实就是想说这个。CD明明是一个各种指标上都优越于黑胶的介质,为什么许多人却在追求70、80年代的老唱片,而且两者确实有明显的听感区别?一言以蔽之:万恶的响度战争

在追求“越来越响”的前提下,导致音乐的平均音量(我们用一个简单的客观指标:RMS)不断上升,而波形的振幅极限则是固定的0 dBFS,所以能做的只有不断压缩动态范围,使得音乐越来越平(再多不再展开,参见旧文)。

响度战争在进入21世纪之后已经基本进入一个平稳期,基本商业作品(指我一般听的日本ACG)稳定在单边动态范围(RMS->Peak)9-11dB这个数字上。

眼尖的可以发现,响度战争这个问题,和CD vs HR又是没有直接关系的:你完全可以塞高动态范围(因而平均音量也要小很多)的母带进CD(严谨地说,高动态范围配合高量化精度当然最好,但是CD的位深一般也绰绰有余了),只是厂商为了听起来够响不这么做而已。

幸好,HR一般是面向所谓audiophile的,所以比较重视这个问题,不会过度压缩动态范围。而这,也几乎是任何新发行音乐唯一值得追求HR的原因。

反过来讲,如果你发行的HR和CD完全一样的动态范围、更没有mastering上的区别,仅仅是数字96/24好看,那真的有意义么?请容我大言不惭地说一句,没有!

这里让我们有请Lantis选手:

TitleVersionRMSPeakDiff
Glow MapCD-8.84-0.18.74
Glow MapHi-Res-8.83-0.18.73
あの花のようにHi-Res-9.42-0.68.81
なんどでも笑おうHi-Res-16.8016.8
眠り姫 [ORT]Hi-Res-16.33-0.0916.24

不用多说什么了吧。下面两首是作为对比的哥伦比亚的最近发行的的HR。HR和CD完全一样的动态范围就不提了,更可怕的是烂铁的CD们的RMS已经拉到了-8.x这个水平,还剩多少动态范围可想而知了。

当然这个问题不是只有烂铁一家有,只不过一般没这么夸张。看看もちょ最近几张CD(这里同时列出单曲版和专辑版,因为部分有变化):

ArtistSgAlSongSourceVersionRMS (dB)Peak (dB)Diff (dB)
麻倉もも52365×LOVEAlbumCD-9.922-0.0289.894
麻倉もも52365×LOVESingleCD-10.847-0.00110.847
麻倉もも52365×LOVESingleHi-Res-12.595-0.19812.397
麻倉もも52365×LOVEAlbumHi-Res-11.323-0.20111.122
麻倉もも62シュークリームAlbumCD-10.388-0.00110.388
麻倉もも62シュークリームSingleCD-10.928-0.00110.927
麻倉もも62シュークリームSingleHi-Res-12.639-0.19812.442
麻倉もも62シュークリームAlbumHi-Res-11.805-0.20011.605
麻倉もも62スマッシュ・ドロップAlbumCD-9.808-0.0019.808
麻倉もも62スマッシュ・ドロップSingleCD-9.990-0.0019.990
麻倉もも62スマッシュ・ドロップSingleHi-Res-11.945-0.19811.747
麻倉もも62スマッシュ・ドロップAlbumHi-Res-11.247-0.20011.047
麻倉もも72“さよなら”聞いて。AlbumCD-10.814-0.00110.814
麻倉もも72“さよなら”聞いて。SingleCD-9.392-0.1139.279
麻倉もも72“さよなら”聞いて。SingleHi-Res-10.057-0.1169.942
麻倉もも72“さよなら”聞いて。AlbumHi-Res-12.201-0.20112.000
麻倉もも72ユメシンデレラAlbumCD-10.376-0.00910.367
麻倉もも72ユメシンデレラSingleCD-9.107-0.1748.934
麻倉もも72ユメシンデレラSingleHi-Res-9.709-0.1729.537
麻倉もも72ユメシンデレラAlbumHi-Res-11.783-0.20111.582

もちょ早期几张也存在CD版和HR版动态范围完全一样的问题,不过最近发行的至少能多出2dB左右。另外比较搞笑的是同样是音雨人,制作还有细微的差别,もちょ这里可以看到HR版一般有很多余(正确制作的音频有没有headroom,并没有任何区别)的-0.2dB的headroom,而ナンス的碟则基本全都是CD、HR无论RMS/Peak都完全一样的。手头的CD没抓只存了HR版,就不贴数据了。

不过,不同动态范围听起来区别大不大?这个和个人听力、设备、以及更重要的音乐类型还是关系比较大的(例如交响乐一般很需要大动态),我一般听听日呆流行也听不太出区别(事实上,为了车上放歌方便,我放手机的音乐全都是手动压缩过的动态范围均衡过音量的,我有罪)。但这至少是一个实打实、肉眼可见(笑)的客观的区别。

外一则:Python的音频库

在写DR计算的脚本时,发现Python的音频处理库中,似乎并没有一个明显的first choice。当然,数学计算部分都是用Numpy做的,我这里需要的仅仅是一个解码read的库而已。

搜刮了一阵,大概有这么一下几个选择,这里简单介绍下区别:

def read_wavefile(f): 
    from scipy.io import wavfile
    samplerate, data = wavfile.read(f)
    return data, samplerate

最简单的scipy里的wavfile,基本不支持wave/PCM之外的任何类型。输出就是原始整型,取决于位深,int16或者32。注意输出顺序是采样率/值,我颠倒了下便于和别的几个一致。

def read_sf(f):
    import soundfile as sf
    return sf.read(f) 

SoundFile库。输出似乎永远是float64。支持的格式比上面多,但是不支持m4a(好像支持raw AAC?)。

def read_librosa(f, resampling=None):
    import librosa
    data, samplerate = librosa.load(f, sr=resampling, mono=False) #mono by default, resampling super slow
    data = np.transpose(data)
    return data, samplerate

librosa。其本质是调用SF(上述)或者audioread,所以支持的格式也有限。另外参见注释:默认是mono输出很迷惑,自带的resampling巨慢。值的矩阵要转置下和别的统一。好像永远是float32。

def read_pydub(f, normalized=True):
    import pydub
    a = pydub.AudioSegment.from_file(f)
    # a = a.set_frame_rate(44100)
    y = np.array(a.get_array_of_samples())
    if a.channels == 2:
        y = y.reshape((-1, 2))
    if normalized:
        if y.dtype == np.int16:
            power = 15 
        elif y.dtype == np.int32:
            power = 31
        else:
            raise Exception
        return np.float32(y) / 2**power, a.frame_rate # convert to float32 should be more than enough
    else:
        return y, a.frame_rate # y is same as PCM (int16 or 32)

pydub是我比较推荐使用的库了,他是调用FFMPEG来解码的,所以基本支持任何格式。可以通过set_frame_rate来resampling。唯一的问题就是他默认输出的格式和别人比较与众不同,所以要通过上面这一坨子来输出和别人一样的东西。

这里的normalized是指把PCM的整型normalize到[-1,1]的float,并不会改变振幅啦。因为我后面发现做数学计算的时候整型会比较烦,所以我直接在这里面转了float32。

题外话,int16转float [-1,1]无论是除以2^15还是2^15-1都会有小问题(前者会导致32767无法变成1,后者会导致-32768溢出,虽然业界惯例是前者),不是左右对称的辣鸡有符号整型真的超纠结……

另外一个巨坑是如何判断np.array的dtype,参见这个SO,辅助阅读这个

最后前几天发现pydub有个bug:读取24bit的wav巨慢,比同样的FLAC慢几十倍,原因不明。

乐天的杂志放题

本月起Amazon的Kindle Unlimited不知道为什么突然不再放声A、声G和Animedia了。本来怀疑是因为本月发行时间较早导致的未能同步更新,结果过了一周之后也没有。再加上Animage有正常放出,那就不得不怀疑是这些杂志退出了Unlimited了。虽然目前还抱有下个月观察一下的希望,不过也要先研究下别的路子。

上文有提过BW的放题服务没有声G,所以我随便浏览了下别的几家——乐天的很吸引眼球。价格低廉(月供380日元),可以PC、App阅览,而且网站做的还不错,最重要的是上述那些杂志都有。可以试用一个月,所以就先来白嫖试试。

浏览器看需要日本IP,app则不需要(仅测试安卓;app本体需要日区市场才能下载)。

其网页版默认是显示1024px的小图,直接读取(虽然我没搞明白为啥thumb的资源文件直接打不开,但是不重要没细究);双击或者滚轮放大后自动后台读取pdf格式的原始文件然后用pdf.js加载到canvas里。阅览器是angular写的。

本来以为pdf肯定有加密毕竟下下来直接打不开。第一时间肯定是先试试改后缀名,但是改了.jpg之后我用的XnView MP还是打不开。所以我研究了N久的如何hook JS来批量下载blob(手动下载倒是直接就能下),但是也没搞明白,js框架太烦了(顺便一提,不要直接保存canvas,二压姑且不提,canvas是又根据你窗口大小缩放过一次的图。)

回家后,想先用FlexHex看下那pdf文件的header,结果发现家里用的ACDSee直接tm就把我改过后缀的图打开了……对比了下header,那个所谓的pdf好像就是在一个JPEG文件前面加了几百个Byte的伪PDF文件头,ACDSee和PS的鲁棒性都比较强直接就能读,XnView MP比较严格,没有看到JPEG的文件头就不行。简单地搜索FF D8 FF然后把前面的bytes删掉之后,就和正常的JPEG一样了。

之后又费了些功夫写了个脚本,可以直接给个网址自动下载所有图片外加后处理。中间碰到的坑是Python的requests读取到MozillaCookieJar中expiration为0的session cookie会自动无视,要手动强制改下时间。

顺便一提,其资源文件名顺序都是按左开来排序的,对于这些右开的杂志,下下来就会变成19、18、21、20这样子,还得每两页swap一下(封面封底不动)。

之前说过,之所以会选择Kindle Unlimited而不是其他一些便宜多的同类服务,纯粹是为了提取方便便于收藏。既然这个也能这么简单地下载,那确实挺让人心动了。

不过,下载方便只是一方面,重头戏自然是图像质量。由于这个可以直接下载到网站提供的“原图”,所以首先就杜绝了BW那种原始资源就是混淆过的,你重新拼起来后所以为了防止二压只能被迫存成PNG的体积注水问题。而且更可怕的是,其原图是3072px高,比Amazon的1920px和BW的20xx px都要高得多。而且分辨率是真实的,并非放大,看文字部分的锐度就很明显(上文说过,BW网页版虽然看似有2000,但是原始资源即使1:1也会发虚,有水分)。

但是!一张3000px的图只有几百K,这JPEG质量相信不用说也能猜到有多惨了——70%,4:2:0。如果仅仅是这个我觉得还能忍,因为缩到1920px之后的信息熵估计也没差到哪里去嘛,但是还有个无比纠结的颜色问题。

之前提过BW的声A和Kindle完全一样,但是声G略有偏色;结果到了这边,好像所有的杂志颜色都和Kindle不一样——颜色比起Kindle版,要深非常多(注意,和BW的偏法还不一样)。虽然单独看几乎不会觉得有啥问题,但是和Kindle比了比还是觉得Kindle好些。而且Kindle的声A的画质真的高(95%,4:4:4),这70%的JPEG缩2/3估计也打不过。声G倒是另说,Kindle版的图像虽然名义上是95%,但是有色度抽样(4:2:0)外加是用极差缩放算法缩出来的,有很明显的狗牙和JPEG artifact。

说了这么多来看几个例子。先看看声G。

先对比颜色:

(其实单独放一张图不太客观,毕竟不知道照片本身调色是什么风格。整本一起看会更准确点。)

再来看看细节:

(推荐查看原图)多了那么多分辨率,确实文字还是清晰多了。不过也能看到JPEG artifact之多。

声A我们换个比法,我把这个3000px的图缩到1920然后和Kindle版side by side对比下。

左Kindle,右Rakuten

Hmmm..好像也不是很差,而且有人估计更喜欢这颜色而嫌左边太亮?

对比完,于是我更纠结了。虽然3k的分辨率是很有吸引力,但是颜色问题果然太重要了。如果Kindle能够恢复,我还是主力收集Kindle的版本好了,这个和BW的可以当备胎。

两个Win 7 CMD的bug

短文。

这两个月内遇到的问题,虽然Win 7已经退环境了也不指望修复,但是这俩问题都是我搜了半天也几乎完全搜不到任何信息的,觉得有必要稍微记录下。

Bug 1:输入和terminal宽度相等的字符数,会莫名换行

可以用以下脚本测试:

Python:

import shutil
columns, rows = shutil.get_terminal_size(fallback=(80, 24))
print('Columns:', columns)
print('-------------------')
print('a'*(columns)) # line breaks
print('-------------------')
print('a'*(columns-1)) # works fine
print('-------------------')

Node.js:

console.log('-------------------------------start-------------------------------');
var col = process.stdout.columns;
console.log("a".repeat(col))
console.log('--------------------------------end--------------------------------');

在CMD、PowerShell甚至VS Code里调用都会出现换行bug,无论column是多少:

cmd.exe
In VS Code

这个Bug是在使用https://github.com/Last-Order/Erii这个框架时发现的。它调用了一个叫clui的库,里面有条fill()命令就是把整行用空白字符给填满(便于overwrite已有内容),结果就导致多出很多空行。

Bug 2: 用C#的Process启动cmd的bug

标题太长了写不下,这个behavior是这样的:

Process myProcess = new Process();
myProcess.StartInfo.FileName = @"cmd.exe";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.RedirectStandardOutput = false;

myProcess.Start();
myProcess.StandardInput.WriteLine("echo test > 1.txt");

如果你用Process()来启动cmd.exe,并且重定向stdin,但是不重定向stdout,会出现以下奇怪现象:

  1. 在VS里debug时,会发现stdout也被重定向(弹出的cmd.exe里没文字),但是功能好像还基本都正常(比如上述的范例,会真的执行echo test到1.txt)。
  2. 如果编译好的程序直接双击运行,则cmd会显示一瞬间立刻crash。自然也不会执行任何你WriteLine进stdin的东西。
  3. 据说这个问题似乎只有WinForms程序会有,Console程序不会。(未测试)

这个问题其实我N年前还在用C#的时候就发现了,只不过今天碰巧又在别人写的程序里遇到(作者肯定是用Win 10的,所以没碰到)。介于这个bug在N年前Win 7还是主流的时候就有了,我寻思应该很多人问过才对;但是我找了好久,虽然找到一万个workaround,但是从来没人正式提到这个bug,直到看到这个贴(发表于2010年)。这里,作者很完整的描述了这个现象,但是很显然,依然没有人修复,仅有的几个回复也是牛头不对马嘴(顺便吐槽,这也算是网上问技术问题回答者的通病了)。

TrySail Personal Best

TrySail_-_Youthful_Dreamer_Promo

祝debut五周年!

Best Song

Honorable mentions

オリジナル。
TryAgain
ホントだよ
azure
Make Me Happy?

Top 10-4

10) Journey
9) あかね色
8) センパイ。
7) ひかるカケラ
6) バン!バン!!バンザイ!!!
5) whiz
4) adrenaline!!!

Top 3

3) primary

180520 2nd Tour_20200512_184305.626

2) disco

180520 2nd Tour_20200512_184346.305

1) Youthful Dreamer

170226 1st Tour_20200512_184505.585

Best MV

(每个最多入选一项)

剧情

3) WANTED GIRL
2) ひかるカケラ
1) センパイ。

06 センパイ。 (BDrip Hi10P flac 29.970).mkv_20200512_185706.010

美术

3) オリジナル。
2) Free Turn
1) azure

12 azure (BDrip Hi10P flac 23.976).mkv_20200512_185821.745

综合

3) TryAgain
2) Youthful Dreamer
1) adrenaline!!!

08 adrenaline!!! (BDrip Hi10P flac 23.976).mkv_20200512_190128.036

附录:麻倉もも Best Song

Honorable mentions

Run for you
トラベリータイム
“さよなら”聞いて。
スマッシュ・ドロップ
トクベツいちばん!!

Top 10-4

10) No Distance
9) さよなら観覧車
8) 365×LOVE
7) Good Job!
6) 箱庭ボーダーライン
5) パンプキン・ミート・パイ
4) 今すぐに

Top 3

3) ユメシンデレラ
2) シュークリーム
1) 花に赤い糸

180520 2nd Tour_20200512_192212.259

附录:夏川椎菜 Best Song

Top 10-4

10) ラブリルブラ
9) キミトグライド
8) ナイモノバカリ
7) イエローフラッグ
6) フワリ、コロリ、カラン、コロン
5) gravity
4) ファーストプロット

Top 3

3) シマエバイイ
2) パレイド
1) ステテクレバー

190804 3rd_20200512_192641.811

Agapanthus (麻倉もも) 的视频的相关技术信息

短文。

首先说《今すぐに》。

这是专辑的第二主打歌(自封),个人很喜欢的藤田麻衣子创作。在发售前两天公开的后来补拍的MV——YouTube有完整版,但是iTunes/mora等也有在卖。

本来没准备买,毕竟mora和iTunes都写的是SD画质那我还不如直接看YouTube,结果看到推特有人提iTunes其实有高清画质。本着“肯定是upscale的吧”去买了个结果挺惊喜,确实是高清画质(呃,很难说是否原生1080,但至少秒了mora和YouTube版)。

iTunes下载的时候要注意勾选一个下载最高清画质的选择,否则会下载720p(事实上由于我勾选的时候它已经开始下载,第一次下载到了720p的。我删了重下才下到1080p)。iTunes的版本其实是anamorphic的1440×1080,V+A~=5Mbps。

另外iTunes是真tm难用。

23.976fps录制,但是mora版和iTunes都4重复1插帧到29.97。

mora的SD版则出了和之前在《フワリ、コロリ、カラン、コロン》遇到过的同样问题,视频比例不对——虽然看似是854×480,但是实际变宽了,两侧有出血。根据上次的分析,应该是mora总是会按照1.78:1->1.8:1(索尼系DVD应该要有的操作)进行一次比例変换(然后切掉两侧),但是如果提供的raw本身就已经是16:9的话就会变换过度,变成现在这样。

下面图片对比:

歌曲《Agapanthus》的MV是BD,所以没啥好说。23.976制作。

比较容易令人纠结的自然是那个DVD带的Peachy! live的影像。

按照惯例索尼应该是1.8:1了,但是我们还是要验证下的。唯一可以验证的资源就是当年もちょ直播时放的花絮片段了。结果我一看,几乎所有镜头的分镜都和DVD版完全不一样——这怎么比嘛?

又仔细看了半天,发现有几个镜头其实是一样的,但是使用了不同的crop。我费了半天劲找出来三个镜头,对比了下。先说结论:确实DVD还是应该用1.8:1才和YouTube一致。

下面帖对比图。

场景1,原图(DVD拉伸到720p便于对比,下同):

YouTube版做纯Crop,DVD调整比例后对比:

aaa

场景2,原图:

DVD版crop、改变比例后对比(下面加了白边便于和YouTube版高度一致):

aaa

场景3,原图:

对比:

aaa

上面只是客观对比,而且假设YouTube版本正确。

主观判断的话,大部分近景感觉都OK,但是某些远景总感觉用1.8:1会人物太扁,虽然说区别很小就是了。

而且影片最开始有个3DCG的短片,总感觉那个月亮只有16:9才是正圆……

更新:又仔细对比了下。似乎还是1.8:1的月亮更圆!

aaa

总之还是相当纠结。所以DVD怎么还没死??