第75話の検査台で鳴った短い音を、イトは二つのsignal lampへつないだ。
低い確認音は、blue lamp。
高い警告音は、amber lamp。
source generatorでは、二つの波がはっきり違う。
low tone 2 kHz
high tone 6 kHz
ところがcaptureしたdataを再生すると、二つとも同じ低い音に聞こえた。
sample列を開く。
2 kHz at 8 ksample/s +1, 0, -1, 0, +1, 0, -1, 0 ...
6 kHz at 8 ksample/s +1, 0, -1, 0, +1, 0, -1, 0 ...
違う波だったのに、残った点は同じ並びだ。
イトはhigh tone側のvolume sliderへ手を伸ばした。
「高い音を大きくすれば、再生するときに区別できるかも」
次のtimelineでは、low toneが通常frame、high toneが停止frameを選ぶ。
同じsample列のまま渡せば、二つのsignalを別のtimecodeへ結び付けられない。
音量を変えても、失った速さは戻らない
ユイは、volumeを半分にした試作を一件だけ再生した。
点の高さは小さくなった。
けれど、点が現れる時刻の並びは変わらない。
音は小さくなっても、6 kHzだった証拠は戻らなかった。
イト
音の大きさを変えても、波が一秒に何回揺れたかは作り直せないんだ
ユイ
残っていない違いを、再生側のvolumeで推測することになります
マコト
点を取ったあとではなく、取る間隔を決めた場所へ戻ろう
Picoはvolumeにもcapture clockにも触れない。
二つのwaveformと同じsample列の間を、cyan lightで結んだだけだった。
三つの直し方
A:high toneのvolumeを変える
amplitudeは変わる。
しかしfrequencyを取り違えた原因は残り、元の二つの波を正しく保存したことにはならない。
B:同じsample列の間へ、あとから点を足す
線は滑らかに見える。
けれど新しい点は、すでにある同じ列から計算したものだ。二つに同じupsamplingをすれば、区別できない関係も残る。
C:capture前へ戻り、入力帯域とsample rateを選び直す
取りたいhighest frequencyを確認する。
それより十分高いsample rateへcapture clockを替え、sample rateの半分以上を抑えるinput filterを通してsourceからrecaptureする。
イトはvolume試作を閉じた。
upsampling panelもoutput側から外した。
「C。なくした点を想像で足さない。違う波が違う点として残るところから取り直す」
samplingは、時間に目盛りを置く
音の波は、時間とともに連続して変わる。
linear PCMでは、その値をregular intervalでsampleとして記録できる。
sample rateは、一秒間に何回sampleを取るか。
8 ksample/s one secondに8,000回
16 ksample/s one secondに16,000回
画像の32×32 gridでは、positionをxとyで選んだ。
mono audioのこのfixtureでは、sampleは一つのchannelの特定時刻にある値だ。
横へ進む住所が、時間になる。
sample rateを上げれば、同じ一秒へ置く目盛りは増える。
ただし、あとから同じ点の間を細かく埋めることと、sourceを細かな間隔でcaptureし直すことは同じではない。
半分を超えた波が、低い波へ折り返した
sample rateの半分に当たるfrequencyを、Nyquist frequencyと呼ぶ。
8 ksample/sなら、Nyquist frequencyは4 kHz。
今回のhigh toneは6 kHzで、その範囲を超えている。
8 ksample/sの時刻だけでcosine waveを観測すると、2 kHzと6 kHzが次の同じ列へ重なった。
sample index 0 1 2 3
2 kHz +1 0 -1 0
6 kHz +1 0 -1 0
高いfrequencyが、低い別のfrequencyとして現れるこの折り返しがaliasingだ。
二つのsource waveが、いつでも必ずこの四点になるわけではない。phase、waveform、sample rateが変われば列も変わる。
ここでは違いが消える仕組みを見えるようにした、phaseを固定したclosed cosine fixtureだ。
イトがsample clockをsource側で替えた
保存した元の二toneは、そのまま残した。
イトはcapture unitを停止し、source generatorとの間へinput low-pass filterを入れた。
16 ksample/sのNyquist frequencyは8 kHz。
filterは、capture範囲を超える8 kHz以上の成分を強く減らす設定にする。
取りたいhighest tone 6 kHzに対して、16 ksample/sは2倍を超えている。
イトは自分の手でsparse 8 ksample/s clockを外し、dense 16 ksample/s clockをcapture前のslotへ入れた。

二toneを、sourceから一件ずつrecaptureする。
sample rate 16 ksample/s
Nyquist frequency 8 kHz
highest wanted tone 6 kHz
post-capture points add 0
新しいsample列の先頭を比べる。
2 kHz +1, +0.71, 0, -0.71, -1, -0.71, 0, +0.71 ...
6 kHz +1, -0.71, 0, +0.71, -1, +0.71, 0, -0.71 ...
今度は、同じではない。
二つのlampが、別々に点いた
イトは、decoderへlow toneのtest sampleを一件渡した。
2 kHzとして検出され、blue lampだけが点く。
次にhigh toneを渡す。
6 kHzとして検出され、amber lampだけが点いた。
low tone route blue only
high tone route amber only
sample collisions 0
volume workaround 0
source recaptures 2
イトは二つのtoneとsample fingerprintを自分で照合し、そこで初めてtimelineへのhandoffを許可した。
二つのsignalは、別のtimecodeを待つtrayへ分かれて入った。
sample rate、bit depth、bitrateを混ぜない
sample rateは、時間方向にどれくらい頻繁に測るか。
bit depthは、一sampleの値をどれくらい細かな段階で表すか。
bitrateは、一秒あたりに運ぶbit量。channel数、sample format、codec、compressionなどの条件にも左右される。
今回直したのは、sample rate不足によるfrequencyのaliasingだ。
bit depthを増やして一つ一つの高さを細かくしても、8 ksample/sで取る時刻が同じなら、今回重なった2 kHzと6 kHzの時間パターンは分かれない。
MP3 / AAC / WAVの形式比較やcompression trade-offも、別の問題だ。
最初の一手は、聞こえた音へfilterを重ねることではない。
1. sourceで区別したいhighest frequencyを決める
2. inputをNyquist未満へband-limitする
3. 2倍を超えるsample rateを選ぶ
4. sourceからrecaptureする
5. 一件ずつsample列と再生結果を比べる
二つの音に、まだ再生時刻がなかった
blue trayとamber trayには、区別できるsample列が入った。
それでも、animation screenへは何も起きない。
low toneを最初のframeへ置くのか。
high toneを停止frameの直前へ置くのか。
sample列だけでは、映像のどの瞬間と合わせるかが決まっていない。
イトは、二つのtrayをtimelineの上へ運んだ。
点をあとから増やすのをやめたから、二つの音は別の速さとして残った。
次に必要なのは、その違いをいつ鳴らすかだった。
「音のsampleと画像のframeは、どの時計で待ち合わせるの?」
次回、ピコルート第77話。
動画dataは、frameとaudioをどう同期する?

