SQLiteのボトルネックはディスクの遅さではない:ロックとfsyncをPythonで実測する

「ファイルベースだから遅い」は本当か SQLite をサーバー用途に使う話をすると、たいてい「やめておいたほうがいい」と言われます。これ自体はでたらめな脅しではなく、SQLite の公式ドキュメント(Appropriate Uses For SQLite )自身が、同時書き込みの多いサービスにはクライアント/サーバー型のデータベースを勧めています。では、なぜ駄目なのか。理由を考え始めたとき、まず思い浮かぶのはこんな筋書きではないでしょうか。SQLite の実体はただのファイルで、ファイルの読み書きはディスク I/O。Redis のようなキャッシュ(メモリ上でキーと値を預かる、キャッシュ用途の定番サーバーです)が「メモリで持つから速い」と説明されるのなら、その裏返しで、ディスクに読み書きする SQLite は遅いはずだ——一見、筋が通って聞こえます。 本当にそうか、まず手元で測ってみます。10 万行のテーブルに主キーで 1 件ずつ問い合わせる、キャッシュ用途を想定したいちばん素朴な読み取りです。コードは Python の標準ライブラリだけで動きます。実験はすべて使い捨ての Docker コンテナ(Linux)上で実行していて、再現手順は記事末尾にまとめました。 import sqlite3, time, random con = sqlite3.connect("cache.db") con.execute("CREATE TABLE kv (k TEXT PRIMARY KEY, v TEXT)") with con: con.executemany("INSERT INTO kv VALUES (?, ?)", ((f"k{i}", "x" * 100) for i in range(100_000))) keys = [f"k{random.randrange(100_000)}" for _ in range(200_000)] cur = con.cursor() t0 = time.perf_counter() for k in keys: cur.execute("SELECT v FROM kv WHERE k = ?", (k,)) cur.fetchone() print(200_000 / (time.perf_counter() - t0)) 手元(Apple シリコンの Mac 上の Linux コンテナ、SSD)ではこうなりました。 ...

公開: 2026年7月18日 · Toshihiko Arai
閉鎖・バースト・遷移という3段のタイムラインで破裂音ができている図

「た」は音ではなく出来事 ── 子音の正体(後編・破裂音)

前編 では、「さ」の子音 s を白色ノイズの成形で作りました。摩擦音は音源こそノイズですが、「すーっ」と伸ばせるぶんだけ、まだ母音の親戚のような扱いができた——フィルタを設定して鳴らしっぱなしにすればよかったわけです。 後編の相手はそうはいきません。「た」「か」「ぱ」。試しに「た」の子音だけを伸ばそうとしてみてください。「たーーー」と言っても伸びているのは後ろの「あ」で、t 自体はどうやっても伸ばせません。伸ばせる状態がそもそも存在しないからです。この仲間は破裂音と呼ばれ、口の中を一度完全にふさぎ、ためた息を一気に開放して作ります。その中身は、鳴りっぱなしの音ではなく、数十ミリ秒のあいだに決まった順番で起きる一連の出来事です。 「た」を解剖する 「た」と言った瞬間の音を、時間×周波数の平面(スペクトログラム)で模式的に描くとこうなります。 まず①閉鎖。舌先を歯ぐきに押し当てて口をふさぎ、息の圧力をためます。外に出る音はゼロ、およそ0.1秒弱の完全な無音です。面白いのは、この「音がないこと」自体が子音の部品だということです。無音の谷があるからこそ、次の破裂が破裂として聞こえます。実際、日本語はこの無音の長さを聞き分けていて、「あた」の閉鎖を長く引き伸ばすと「あった」になります。促音「っ」の正体は、長めの無音なのです。 次に②破裂。ふさぎを開放した瞬間、たまった圧が一気に抜けて、「プツッ」という10ミリ秒ほどの短いノイズが弾けます。バーストと呼ばれる成分で、破裂音の中で唯一「音が鳴っている」部品ですが、あまりに短いので単体で聴いてもクリック音にしか聞こえません。 最後に③遷移。破裂の直後、口は子音の構えから次の母音「あ」の構えへ動いていきます。口の形が動けば、フォルマント (口の共鳴で強調される周波数の山)も動く。つまりフォルマントが、子音の構えの位置から母音の定常位置へ、50ミリ秒ほどの坂を滑り降りていきます。このフォルマント遷移が終わると、ようやく④母音の定常状態に着地します。 ①無音、②バースト、③坂、④定常。「た」の子音部分とは①〜③の合計およそ0.14秒の段取りのことで、どこにも保てる状態がありません。前編の言い方を借りれば、摩擦音がまだ「状態」の顔も持っていたのに対し、破裂音は純粋な「出来事」です。作る側の仕事も、フィルタの設定から時間の設計へと完全に切り替わります。 坂の入り方だけで「だ」が「が」になる では「た」と「か」と「ぱ」は何が違うのでしょうか。ふさぐ場所です。「ぱ」は唇で、「た」は舌先で、「か」は舌の奥で口をふさぎます。ふさぐ場所(調音位置と呼びます)が違うと、②バーストの音色と、③遷移の坂の出発点が変わります。ぱ行の破裂は低くこもった「ポッ」、た行は高く鋭い「ツッ」、か行は中域に固まった「コッ」。そして破裂した瞬間の口の形が違うのですから、そこから母音へ向かうフォルマントの坂も、それぞれ別の場所から始まります。 この「坂の出発点」が、実は子音の聞き分けの決定打になっています。それを一番きれいに見せてくれるのが、有声の仲間「ば・だ・が」です。 どちらのパネルも、バーストは同じ、着地する母音も同じ「あ」。違うのは2番目のフォルマント F2 の坂の入り方だけです。低いところから駆け上がってくれば「ば」、少し上からすっと降りてくれば「だ」、もっと高いところから深く落ちてくれば「が」。音として鳴っている部品はほとんど共通なのに、ほんの50ミリ秒の坂の形だけで、耳は「唇でふさいだな」「舌先だな」「奥だな」と聞き分けてしまいます。これは1950年代に音声合成の研究者たちが人工的な音で確かめた古典的な発見で、子音の情報が「音そのもの」ではなく「母音への入り方」に載っていることを示しています。 触ってみる その時間の設計を、スライダー3本で組み立てるデモです。「た」「か」「ぱ」のボタンを押すと、閉鎖→バースト→遷移→母音のタイムラインを Web Audio が実行します。閉鎖の長さを伸ばすと「あた」が「あった」になり、バーストを0%にすると弾けが消え、遷移を120msまで引き伸ばすと「わ」や「や」のような滑らかな音に化けていく——3つの部品がそれぞれ何を担っているかを、壊しながら確かめられます。下の実験パネルでは、F2 の出発点のスライダーを動かすだけで「ば→だ→が」が入れ替わる境目を探せます。 うまく表示されないときは、デモを別タブで開く 。 聴いてみると分かるとおり、出てくるのは「たしかに、たっぽい」という音であって、人の「た」そのものではありません。実はこれこそが破裂音の性格です。閉鎖の長さが数十ミリ秒ずれる、バーストの帯域が少し違う、坂の形がわずかに崩れる——そのどれもが聞こえを変えてしまうほど、耳は破裂音の時間構造に敏感で、パラメータをきっちり合わせても「それっぽい」の先へはなかなか行けません。母音なら3本のフィルタで済んだのに、子音では研究者たちが何十年もかけて規則を磨いてきた理由が、スライダーを触っているだけでも実感できると思います。 どう実現するか 作る側から見ると、破裂音の実装とは「無音を含めたスケジュール表を書くこと」です。Web Audio API には、パラメータの未来の値を予約する仕組み(setValueAtTime と各種 Ramp)があるので、タイムラインをそのまま書き下せます。 const t0 = ac.currentTime; const tBurst = t0 + 0.07; // ① 閉鎖 = 0.07秒なにも置かない // ② バースト:短いノイズを帯域で着色(た=4200Hz / か=1700Hz / ぱ=700Hz) burstGain.gain.setValueAtTime(0.5, tBurst); burstGain.gain.exponentialRampToValueAtTime(0.001, tBurst + 0.012); // ③ 遷移:フォルマントのフィルタを出発点に置き、母音へ滑らせる const tv = tBurst + 0.03; // 声帯の始動 bpf2.frequency.setValueAtTime(1800, tv); // F2 の出発点(た の構え) bpf2.frequency.linearRampToValueAtTime(1250, tv + 0.05); // 「あ」へ50msの坂 vowelGain.gain.setValueAtTime(0, tv); vowelGain.gain.linearRampToValueAtTime(0.9, tv + 0.02); // ④ あとは母音の定常 C風に書くなら、サンプル番号がどの区間にいるかで振る舞いを切り替えるだけの、行儀のよい状態機械になります。 ...

公開: 2026年7月18日 · Toshihiko Arai
濃紺の背景に、WEB MIDIの大きなタイポグラフィ、ピアノロールを表示したブラウザウィンドウ、そこへ差し込まれるMIDIケーブルと鍵盤を描いたレコードジャケット風アイキャッチ

ブラウザが楽器とつながる ── Web MIDIとコンピューターでの扱い

前回の番外編MIDI編① で、MIDIは音の波形ではなく「いつ・どの高さを・どの強さで弾け」という数バイトの指示を送る規格だ、という話をしました。ただ、指示は受け取り手がいて初めて意味を持ちます。届いた3バイトを解釈して、鳴らして、覚えて、並べ替える。その受け取り手の主役が、コンピューターです。 そして今は、専用ソフトを買ってこなくても、この受け取り手を自分で書けます。ブラウザのJavaScriptには、USBでつないだMIDIキーボードと直接会話するためのWeb MIDI APIがあり、届いたバイト列は前回デモで眺めたものとまったく同じ形をしています。MIDIは特別な機材の中だけの話ではなく、コードから触れる身近な信号なのです。 コンピューターが指示に対してできることは、突き詰めるとこの図の3つです。鳴らす、記録する、作り変える。今回はこの3つを、ブラウザの上で実際に組み立てていきます。 ブラウザが楽器とつながるまで Web MIDI APIの流れは、カメラやマイクを使うWebアプリとよく似ています。ページがAPIを呼ぶと、ブラウザがユーザーに「このサイトにMIDIデバイスの使用を許可しますか?」と確認し、許可されて初めてポートの一覧が手に入ります。 入り口はnavigator.requestMIDIAccess()のひとつだけ。返ってくるMIDIAccessオブジェクトの中に、入力ポート(楽器からブラウザへ)と出力ポート(ブラウザから楽器へ)が並んでいます。入力ポートのonmidimessageに関数を登録すれば、鍵盤を弾くたびにその関数へバイト列が届きます。 const access = await navigator.requestMIDIAccess(); for (const input of access.inputs.values()) { input.onmidimessage = (ev) => { const [status, note, velocity] = ev.data; // 例: [0x90, 0x3C, 0x64] if ((status & 0xF0) === 0x90 && velocity > 0) { playNote(note, velocity); // あとは前回の知識で読める } }; } ev.dataの中身は、前回解剖した3バイトそのものです。ステータスの上位4ビットで命令を見分け、ノート番号とベロシティを取り出す。規格が40年変わっていないおかげで、1980年代のシンセをUSB-MIDIインターフェイス経由でつないでも、この数行がそのまま動きます。 対応状況は正直に書いておきます。ChromeとEdge、Firefox(バージョン108以降)では使えますが、SafariはmacOSでもiPhoneでも対応していません。AppleのWebKitチームが、MIDI機器の固有IDがユーザーの追跡(フィンガープリント)に使われることを懸念して実装を見送り続けているためです。接続が許可制なのも同じ理由です。スマートフォンでこの記事を読んでいる方が実機接続を試せないのは心苦しいところですが、この後のデモは実機なしでも最後まで動くように作ってあります。 時刻を付ければ、それはもうシーケンサー 届いたバイト列を鳴らすだけなら、コンピューターは高級なMIDIケーブルにすぎません。面白いのはここからで、届いたイベントに受け取った時刻を添えて配列に積んでいくと、それだけで演奏の記録になります。 const events = []; function record(bytes) { events.push({ t: (performance.now() - recStart) / 1000, bytes }); } 再生は逆再生ならぬ逆過程で、時計を走らせて、時刻が来たイベントから順に「鳴らす」処理へ流し込むだけです。これがシーケンサーの最小形で、DAWのピアノロールで音符をつまんで動かす操作は、この配列のtやノート番号を書き換えているにすぎません。 録音した音声データと決定的に違うのは、時間と音程が別々の数値として持たれていることです。Tape Stopの回 で、テープやサンプルは再生速度を変えると音程まで一緒に変わる、という物理を確かめました。指示の列にはそれがありません。 波形の2倍速は振動そのものの2倍速なので、音程が1オクターブ上がります。指示の列の2倍速は、イベントの間隔を半分にするだけ。各イベントが運ぶノート番号は手つかずなので、音程はそのままです。テンポと音程を独立に扱えるこの性質こそ、打ち込みという制作スタイルの土台になっています。 表情のコントロールも同じ言葉で書けます。ピッチベンドはE0で始まる3バイト(値だけ14ビットに拡張されています)、ビブラートなどに使うモジュレーションホイールはB0 01 xxというコントロールチェンジ。鍵盤のオンオフと同じただのメッセージなので、シーケンサーは区別なく記録・再生できます。前回「指示の缶詰」として紹介したSMF(.midファイル)は、まさにこの時刻付きイベント列をファイルに書き出したものです。 弾いて、記録して、倍速で聴く ここまでの部品を全部つないだデモです。USBのMIDIキーボードがあれば「MIDI機器に接続する」から実機で、なければ画面の鍵盤で、同じように遊べます。 うまく表示されないときは、デモを別タブで開く 。 ...

公開: 2026年7月18日 · Toshihiko Arai
白色ノイズをフィルタで成形すると s の子音になる流れ図

「あ」は作れたのに「さ」が作れない ── 子音の正体(前編・摩擦音)

フォルマント合成の回 で、プログラムは「あー」と歌えるようになりました。ノコギリ波をバンドパスフィルタに通すだけで母音が出る、というのがあの回の話です。気をよくして、次は「さ」と言わせたくなります。「さしすせそ」が言えれば、しゃべりまで手が届きそうです。 ところが、これが作れません。母音マップのどこを探しても「さ」はいないのです。フィルタの設定をどういじっても、出てくるのは「あ」と「お」の中間のようなあいまいな母音ばかり。当然で、「さ」の頭に付いている子音 s は、母音と同じ道具では作れない、材料から違う音だからです。今回と次回の2回に分けて、この子音の正体を追いかけます。前編は「さ」の仲間、擦る子音の話です。 「あー」は状態、「さ」は出来事 まず、母音と子音が何がそんなに違うのかを、波形で見てしまいます。 「あーーー」と伸ばした声は、上の段のように同じ形の波が延々と続きます。息の続くかぎり何秒でも伸ばせて、どの瞬間を切り出しても同じ形。つまり母音とは、口の形(フォルマント)を保てば維持できる定常状態です。フォルマント合成 がやったのは、この状態をひとつ作ることでした。 一方「さ」と言った声の波形が下の段です。前半にはギザギザのでたらめな波、つまりノイズが入っていて、後半で周期的な波に切り替わります。この前半のノイズこそが子音 s の正体で、「さ」という音は、ノイズから声への乗り換えという順番そのものなのです。音というより、始まりと終わりのある小さな出来事と言ったほうが近い。母音を作る道具が「状態を保つ」道具だったのに対して、子音づくりには「時間を設計する」発想が要ります。 音源そのものがノイズになる では前半のノイズは、体のどこで生まれているのでしょうか。「すーーー」と s の音だけを伸ばしてみると分かります。このとき、のどに指を当てても震えていません。声帯は完全に止まっています。鳴っているのは、舌先を歯ぐきのすぐ裏に近づけて作った狭い隙間を、息が無理やり通り抜けるときの音です。狭いところを速い流れが通ると、流れが乱れて渦になり、シャーッという広い帯域のノイズが生まれます。蛇口を強くひねったときの水音や、風がすき間で鳴るのと同じ、乱流の音です。 このように、隙間の乱流を音源にする子音を摩擦音と呼びます。さ行の s、「し」の子音、は行の h、英語の f や th も仲間です。母音のときの声帯ブザーが「ブー」という周期的な音源だったのに対して、摩擦音では音源そのものがノイズに置き換わっている。source-filter モデル(音源×口の形のフィルタ、という声のとらえ方)の枠組みはそのままで、source の側が全とっかえになるわけです。 これはプログラムを書く側には朗報でもあります。ノイズなら簡単に作れるからです。毎サンプル、乱数を出力するだけで白色ノイズ、つまり全帯域が均等に入った「ザーッ」が手に入ります。あとは母音のときと同じように、フィルタで成形すればいい。実際、フォルマント合成の回 で「ささやき声でも母音が聞き分けられる」という話をしましたが、ささやき声とはまさに、声帯のブザーを息のノイズに差し替えた声のことでした。 s と sh を分けるのは、山の位置 同じ擦る音でも、「さ」の s と「し」の sh は明らかに違って聞こえます。s は鋭く高い「スー」、sh は少しこもった「シュー」。この違いは、ノイズのスペクトル(周波数ごとの成分の一覧)のどこにエネルギーの山があるかの違いです。 s は舌先と歯ぐきの間のせまい隙間で擦るので、山が高い周波数(おおよそ5〜8kHz)にできます。sh は隙間が少し奥に下がってやや広くなるぶん、山が低いほう(2〜4kHzあたり)へ降りてきます。口笛で口をすぼめると音程が変わるのと似て、擦る場所と隙間の広さが、ノイズの色を決めるのです。そして「ふ」の f や「はー」の h のように隙間がゆるい子音になると、山はぼやけて、弱く平らな息の音になります。 つまり摩擦音づくりとは、白色ノイズをバンドパスフィルタ(指定した帯域だけを通すフィルタ)に通して、山をどこに立てるかを選ぶ作業です。フィルタの回 では音の明るさを削って作りましたが、今回は削って子音を作る。中心周波数のつまみひとつで、s が sh になり、f になります。 もうひとつ、おまけのような一手があります。「すー」と擦りながら声帯も鳴らすと「ずー」になります。ノイズに声帯のブザーを重ねただけで、s は z に、「し」の子音は「じ」の子音に変わる。有声摩擦音と呼ばれる仲間で、部品としては「ノイズ+ブザー」の足し算です。 触ってみる ここまでの話をそのまま触れるデモを用意しました。鳴っているのはいつも同じ白色ノイズで、フィルタの「山の位置」と「山の鋭さ」だけを動かせます。プリセットの s から sh へ、鳴らしたままスライダーを下ろしていくと、「スー」が「シュー」に化けていく途中も聴けます。有声化ボタンで声帯のブザーを重ねれば z の「ズー」に。下の段では、成形したノイズを母音 とつないで「さ・し・す・ず」と音節にしています。 うまく表示されないときは、デモを別タブで開く 。 ...

公開: 2026年7月17日 · Toshihiko Arai
濃い藍色の背景に、MIDIの大きなタイポグラフィとSOUND NOT INCLUDEDの文字、DIN5ピンコネクタ、90 3C 64のバイト列チップ、ピアノ鍵盤を描いたレコードジャケット風アイキャッチ

音を送らない規格 ── MIDIの歴史とメッセージの仕組み

同じ1曲でも、MP3のファイルはおよそ5MB、いわゆるMIDIファイル(.mid)は数十KBしかありません。桁がふたつ違います。圧縮がうまいからではなく、MIDIファイルは何かを大胆に捨てているからです。捨てているのは、音そのもの。MIDIのデータの中に、音の波形は1サンプルも入っていません。 では何が入っているのか。「いつ、どの高さの音を、どの強さで弾け。いつ離せ」という演奏の指示です。MIDI(Musical Instrument Digital Interface)は、この指示を数バイトのメッセージとして送り合うための、楽器の共通語です。音を作る仕事は受け手の音源に任せて、自分は指示だけを運ぶ。この割り切りがMIDIのすべての出発点になります。 この連載の起点 で、音は1秒あたり44,100個の数値の列だと書きました。録音とは、この膨大な数値の列=鳴った結果を丸ごと保存することです。MIDIはその数値の列すら送りません。保存するのは楽譜にずっと近いもので、だからデータが軽く、あとから音の高さや長さを1音単位で直せて、ピアノの指示をそのままストリングスで鳴らし直すこともできます。録音した歌の音程直しがひと仕事なのに対し、MIDIなら数値をひとつ書き換えるだけです。 メーカーの垣根を越えた1983年 1980年ごろのシンセサイザーは、メーカーごとに接続方式がばらばらでした。電圧で音程を伝えるCV/Gateという方式が広く使われていたものの、電圧と音程の対応ルールがメーカーで違い、別々の会社の機材をつないで合奏させるのは一苦労でした。 そこで1981年、Sequential CircuitsのDave SmithがChet Woodとともに、メーカー共通のデジタル接続規格「Universal Synthesizer Interface」をAES(オーディオ技術者の学会)で提案します。この構想にRoland創業者の梯郁太郎ら日本のメーカーが合流し、仕様を擦り合わせて生まれたのがMIDIでした。1983年1月のNAMMショーで、SequentialのProphet-600とRolandのJupiter-6がケーブル1本でつながれ、片方の鍵盤を弾くともう片方が鳴る様子が初めて公開されます。ライバル同士の楽器が共通語で会話した瞬間です。仕様は同年8月にMIDI 1.0として公開されました。 物理的には5ピンのDINコネクタと、毎秒31,250ビットのシリアル通信。今の感覚では細い回線ですが、送るものが指示だけなので、これで足ります。そしてこの仕様が驚くほど長寿でした。40年以上たった今も、1983年の機材と最新の機材はそのままつながります。2020年に後継のMIDI 2.0が策定されましたが、1.0との互換は保たれたままです。2013年には、SmithとKakehashiの2人にテクニカル・グラミー賞が贈られました。音楽の賞が、音を1音も送らない規格の設計者に贈られたわけです。 中身はたった3バイト MIDIのメッセージがどれくらい簡素か、鍵盤を1回押したときに流れるデータを見てみます。流れるのは次の3バイトだけです。 1バイト目の90をステータスバイトと呼びます。先頭ビットが1になっていて、「ここから命令が始まる」という合図です。上位4ビットが命令の種類(1001なら「弾け」=ノートオン)、下位4ビットが宛先チャンネルを表します。続く2バイトはデータバイトで、こちらは先頭ビットが0。残りの7ビットで、鍵盤のどこか(ノート番号)とどれだけ強く押したか(ベロシティ)を伝えます。60が中央のド、つまりピアノの真ん中あたりのドです。 ここでMIDIの値がなぜ127までなのかという定番の疑問も解けます。1バイトは8ビットありますが、先頭の1ビットを「命令かデータか」の見分けに使ってしまうので、データに残るのは7ビット、表せるのは0〜127の128通りです。ノート番号もベロシティも音量も、MIDIの世界の数値がそろって127止まりなのは、この設計のためです。 鍵盤を離すときはノートオフです。80 3C 00のように専用のステータス(8x)で送るのが正式ですが、実際の機材には「ノートオン(90)でベロシティ0を送る」ことをノートオフの代わりにする流儀も広く根付いています。強さ0で弾け、はつまり離せだろう、という論法です。これは単なる横着ではなく、同じステータスバイトが続くときは2回目以降のステータスを省略してよいというランニングステータスという節約規則があり、オンもオフも90系でそろえるとこの省略がよく効いて、細い回線をさらに節約できたのです。 1本のケーブルで16パートの合奏を送る ステータスバイトの下位4ビットが宛先チャンネルでした。4ビットなので16チャンネル。つまりMIDIケーブル1本の中に、16パートぶんの指示を混ぜて流せます。 受け手の音源は、届いたメッセージのチャンネル番号を見て、ch1はピアノの音色で、ch2はベースで、ch10はドラムで、とパートごとに鳴らし分けます。90 3C 64はch1宛ての「弾け」、91 3C 64なら同じ「弾け」でもch2宛て。宛先が変わるだけで、バイト列の形はまったく同じです。 この仕組みを土台に、1988年には演奏データをファイルに保存する共通形式SMF(Standard MIDI File、拡張子.mid)が、1991年には「音色番号1番はピアノ」「ch10はドラム」といった音色の割り当てまで統一するGeneral MIDIが定められました。どの機材で再生してもそれなりに同じ曲として鳴る「指示の缶詰」の完成です。冒頭の数十KBのMIDIファイルの正体はこれで、ガラケーの着メロが小さなデータで済んだのも、通信カラオケが細い電話回線で新曲を配信できたのも、送っていたのが音ではなく指示だったからでした。 鍵盤を押して、流れるバイトを見る ここまでの話を、目で確かめられるデモを用意しました。画面の鍵盤を押すと、その瞬間に流れるMIDIメッセージが16進数で表示されます。音はブラウザ内のシンセが「指示を受け取った音源」の役を演じて鳴らしています。 うまく表示されないときは、デモを別タブで開く 。 まず鍵盤をひとつ押して、離してみてください。押した瞬間に90で始まる3バイト、離した瞬間に80で始まる3バイトが流れます。ベロシティのスライダーを動かすと3バイト目が変わり、チャンネルを切り替えるとステータスバイトの下位4ビットだけが変わります。ノートオフの流儀を「90 vel 0」に切り替えると、離したときのバイト列がノートオンと同じ90で始まるのも見ておいてください。どのつまみがどのバイトに効くかが結びつくと、MIDIのメッセージはただの表ではなく、読める言葉になってきます。 どう実現するか デモの中身は、MIDIメッセージの組み立てと解釈をJavaScriptで書いたものです。組み立ては、ビット演算で3つの数を並べるだけです。 function noteOn(channel, note, velocity) { // channelは1〜16 return [0x90 | (channel - 1), note, velocity]; } function noteOff(channel, note) { return [0x80 | (channel - 1), note, 0]; } noteOn(1, 60, 100); // [0x90, 0x3C, 0x64] = ch1でドを強さ100で弾け 0x90 | (channel - 1)が、命令の上位4ビットとチャンネルの下位4ビットをひとつのバイトに合成している部分です。受け取る側は逆に、status & 0xF0で命令の種類を、status & 0x0Fでチャンネルを取り出します。規格書の表で見ると無機質なMIDIメッセージも、書いてみればビット演算の初歩だけでできています。デモではこのバイト列を自前のシンセ(Web Audio)に渡して鳴らしていますが、同じバイト列は1983年のシンセにもそのまま通じます。 ...

公開: 2026年7月17日 · Toshihiko Arai
ハイポニカ601で育てたミニトマトの収穫

ハイポニカ601「果菜ちゃん」でミニトマトを室内水耕栽培した記録【東京マンション】

2025年の夏から翌年の冬にかけて、東京のマンションの一室で、ホームハイポニカ601「果菜ちゃん」というキットを使ってミニトマトを水耕栽培した。土をいっさい使わず、水と液体肥料だけで育てる方式だ。窓際に置いた装置に苗を1本だけ植えたところ、レースカーテンに沿って2メートルをゆうに超える高さまで茂り、秋から真冬にかけてだいたい300個ほどの実がとれた。 味は市販のミニトマトと変わらずしっかりしていて、水っぽさもない。室内なので虫が寄らず、トマト最大の敵であるサビダニの被害も出ず、農薬を一度も使わずに済んだ。栽培を終えたのは翌年の1月、真冬でも実はついていたが、2月に小田原へ引っ越すことになり、そこで区切りをつけた。約5か月の記録を、写真をたどりながら残しておく。 育てるのに使ったもの 装置は協和ハイポニカのホームハイポニカ601「果菜ちゃん」 。液肥槽と栽培槽が上下2層になっていて、下の槽にためた液肥水をポンプで汲み上げ、上から滝のように落として循環させる仕組みだ。この「上から落とす」構造のおかげで水に空気が程よく混ざり、根全体に酸素と養分がムラなく回る。あとで触れるが、この点が育ちの良さに効いていたと思う。 肥料は専用のハイポニカ液体肥料 A・Bセット を使った。A液とB液をそれぞれ水で500倍に薄めて使うもので、原液のまま混ぜると沈殿してしまうため、必ず水に別々に溶かす。液肥の濃さの管理にはAPERA EC20 というペン型のECメーター を用意した。ECというのは水にどれだけ肥料分が溶けているかを電気の通りやすさで測る指標で、単位はmS/cm(ミリジーメンス毎センチ)。水耕栽培では、このEC値が肥料の濃さの目安になる。 組み立てと初期設定 届いたキットを窓際で組み立てた。部品はシンプルで、栽培槽、液肥槽、循環ポンプ、給液吐出部、栽培鉢とがく型カバー、培地といった構成になっている。 取扱説明書によると、公称の液肥容量は12リットル。最初に6リットルを入れて循環を確認し、そのあとさらに6リットルを足す手順になっている。ウキの黄色い部分まで水位が下がったら補給の合図で、赤まで下がると危険水位だ。循環ポンプは栽培中ずっと動かすのが基本とされている。メーカーは日光が十分に当たる屋外での栽培を勧めているので、今回のように室内の窓際で育てるのは本来の想定とは少し違う使い方になる。そのぶん、都会の室内でどこまで育つのかという実験でもあった。 室内の栽培環境 置き場所は南向きの部屋の窓際。都内のマンションだが前をビルにさえぎられておらず、日当たりはまあまあある。とはいえ朝日は差し込まず西日も少なめで、南からの直射が入る時間はそれほど長くない。屋外でしっかり日を浴びせる栽培と比べると、日照は明らかに劣る条件だ。育成ライトの類は使っていない。 エアコンは普段どおりよく使った。夏はつけっぱなし、冬は暖房も入れる。ただし温度管理といっても人が快適に過ごすために使っただけで、トマトのために調整したわけではない。植えた時期はやや遅めだったが、種袋にあるとおり秋に実る品種だったので、季節はうまくかみ合った。そして室内ならではの利点として、虫がまったく寄ってこなかった。この一点が最後まで効いてくる。 写真でたどる栽培記録 種は「秋どりミニトマト 甘美」を使った。日付ははっきり覚えていないので、以下は写真のファイルに残っていた撮影日を頼りにしている。 いきなり装置に種をまくのではなく、まず別の容器でスポンジに種を置き、水を含ませて発芽させた。スポンジは601に付属していたもので、100円ショップのスポンジでも代わりになる程度のものだ。何粒かまいて、その中でいちばん元気に伸びた1本だけを選び、葉が開いたところで栽培槽へ移した。大きなキットに対して、植えた苗はたった1本である。 定植から2週間ほどで、ひょろりとした苗がしっかりした株に育ってきた。 9月半ばには最初の花が咲いた。 草丈が伸びてきたので、キットに付属する2段の支柱支持枠を取り付けた。もっとも、この枠は早々に用をなさなくなる。あとで書くように、株はこの枠をはるかに超えて茂っていった。 10月に入ると小さな青い実がつき始めた。 その青い実が、みるみる房になって増えていく。 11月に入ってようやく最初の実が赤く色づいた。ここまでくれば、あとは次々に熟していく。 11月末、まとまった量をざるいっぱいに収穫できた。ここから真冬にかけて、収穫が途切れなく続くことになる。 液肥とECの管理 肥料とECの管理は、正直なところかなり適当だった。最初のうちは取扱説明書を見ながら合わせ、あとは基本的にメーターの表示を見て決めていた。苗がまだ小さいうちは薄めに、株が育つにつれて液肥を足して濃くしていく、という大まかな方針だけを守った。管理はpHではなくECで見ていたが、途中からは測るのが面倒になってやめてしまい、水を足して薄まったかな、という感覚で継ぎ足していた。 参考までに、計測した折の表示を残しておく。組み立て直後の8月20日はおよそ1.5mS/cm。 実がたくさんついた11月19日にはおよそ3.3mS/cmまで上がっていた。 ただしこれらは、その瞬間に画面に出ていた数字にすぎない。直前に水を足したのか肥料を足したのかで値は動くので、「この濃度を保っていた」という意味の数字ではない。目標として一定に保ち続けていたわけではないことは、念のため断っておきたい。 ミニトマトの水耕栽培でどのくらいのEC値が目安になるのか、家庭向けの一般的な推奨レンジを調べてグラフにしてみた。数値の絶対値は品種や気温、栽培方式で変わるので、あくまでざっくりした指針として見てほしい。 苗のうちは薄く、大きくなるにつれて濃く、というのが基本線だ。ここで注意したいのが肥料の窒素分の扱いである。窒素は葉や茎を育てる成分で、これが多いと植物は葉や茎を茂らせる方向(栄養成長)に力を注ぐ。ところが実をつけ始める頃に窒素を与えすぎると、株が栄養成長に傾いたまま、花や実をつける方向(生殖成長)へなかなか切り替わらない。結果として葉ばかりがうっそうと茂って実つきが悪くなる。園芸ではこれを「つるぼけ(樹ぼけ)」と呼ぶ。だから実がつく段になったら肥料は少しずつにとどめ、葉の茂り具合を見ながら加減するのがよいとされている。今回は序盤を薄めにしていたのが結果的に功を奏したのかもしれない。 肥料の足し方にはこの装置ならではのコツがあった。水を補給すると液肥が薄まるので、そのつど液肥を直接タンクへ入れてやる。循環ポンプが水を回してくれるので、あらかじめ混ぜておかなくても勝手にいきわたる。この手軽さは2層循環式のありがたいところだった。 根の張り具合も、この循環のおかげか終始よかった。11月にタンクの中をのぞくと、白く元気な根がびっしり広がっていた。 以前、バケツにエアポンプで空気を送り込む自作の水耕装置を試したことがあるが、そのときは根がここまで生き生きとはしなかった。日当たりの差もあったかもしれないが、上から水を落として空気を巻き込みながら循環させる601の作りは、根に酸素を届けるという点でよくできていると感じた。 水の減り方は生育の段階で大きく変わった。実がなるまでは使う量が少なく、水を足すのは週に1回、多くて2〜3日に1回くらいで足りた。ところが実がついて株が大きくなると、水の減りが一気に激しくなる。葉が増えて蒸散が盛んになるうえ、エアコンで室内が乾くせいもあるだろう。逆にいえば冬場は、装置が加湿器のように部屋をほどよく潤してくれる感覚もあった。 受粉・誘引・剪定 人工授粉はほとんどしなかった。最初に少し花を揺らしてみたものの、どうやら必要なさそうだとすぐに分かった。というのも、株はレースカーテンの内側でちょうど葉のカーテンのように茂り、人がカーテンを開け閉めするたびに葉も花も揺れる。それだけで自然に受粉していたらしく、受粉で苦労した覚えはまるでない。 脇芽はちょこちょこ摘んだが、何本仕立てにするといった管理はいいかげんなものだった。伸びすぎたら先端を切る。切るとまた脇芽が出てくるので、それをたまに摘む。これはふつうのミニトマト栽培と変わらない。ただ、とにかく背が高くなった。身長を軽く超え、窓一面に張り付いて、2メートルは平気で超えていく。ここまで来ると手が届かず管理しきれないので、先端を止めた。 支えには、カーテンレールに紐をかけてつるを吊り上げ、茎を留めていった。付属の支柱支持枠は、この茂りように対してはまるで足りなかった。水耕栽培でここまで大きくなるのかと、正直なところ面食らった。下の写真は11月下旬に撮ったもので、定植からおよそ3か月、日数にして97日ほど。種をまいた日から数えても110日ほどで、たった1本の苗がこれだけの株に育った。 収穫と味 とにかくよくとれた。写真のとおり鈴なりで、途中まではきちんと数えていたが、100個を超えたあたりで数えるのがばかばかしくなってやめてしまった。終盤は毎日いくつか摘む状態で、ざっと見積もって300個ほどにはなったと思う。食べきれずに悪くしてしまったものもあったほどで、知り合いに配りたいくらいの豊作だった。 真冬の1月に入っても収穫は続いた。 ...

公開: 2026年7月16日 · Toshihiko Arai

PostgreSQLはなぜクラッシュしても壊れないのか:WAL(先行書き込みログ)をpsqlで見る

COMMIT した瞬間、PostgreSQL は本体に書いていない PostgreSQL を運用していると、少し不思議に思う場面があります。大量の書き込みが走っているのに、一件の COMMIT はほとんど待たされずに返ってきます。それでいて、サーバーの電源が突然落ちても、再起動すればコミット済みのデータはちゃんと残っています。速さと壊れにくさは、普通なら両立しにくいものです。それでもデータベースは、平然と両方をこなしているように見えます。 この不思議は、COMMIT を「変更をデータファイルへ書き終えた合図」だと思っていると説明できなくなります。実際には、PostgreSQL は COMMIT の時点でテーブルの本体(データファイル)を書き換えていません。先にすることは別にあります。入口で図にすると、素朴なイメージと実際の動きはこう違います。 PostgreSQL は、データ本体を書き換えるより先に、その変更内容をまず追記専用の日誌へ書き終えます。この日誌が WAL(Write-Ahead Logging、先行書き込みログ)です。日誌への追記が終わった時点で COMMIT は完了として返り、本体のデータファイルへの反映はあとでまとめて行われます。 順序を言葉にすると「ログが先、本体はあと」です。たったこれだけの取り決めが、クラッシュ耐性・レプリケーション・任意時点への復元(PITR)という、一見別々に見える機能をまとめて支えています。この記事では、その日誌が実際に伸びていく様子を psql で覗き、kill -9 でサーバーを殺してから自動で復旧するところまでを、使い捨ての PostgreSQL で目の前で起こしてみます。 先にログ、あとで本体 なぜ「先にログ」だと速くて壊れにくいのか、先に理屈を押さえておきます。 テーブルの本体は、行がどのページに入るかがばらばらに決まります。あちこちのページを更新するたびにディスクの離れた場所へ書きにいくのは、順番の定まらない書き込みで、ディスクにとっては不得意な動きです。一方 WAL は、変更内容を起きた順に末尾へ足していくだけの一本のログです。同じ場所へ続けて書き足していく動きはディスクが最も得意とするもので、しかも「末尾まで書き終えた」ことさえ保証できれば、その時点でコミットを確定してよくなります。だから COMMIT は本体の更新を待たずに素早く返せます。 壊れにくさも同じ仕組みから来ます。WAL には「どの行をどう変えたか」が起きた順に残っています。もし本体への反映が途中で電源断に巻き込まれても、再起動後に、直近のチェックポイント以降の WAL を読み直して同じ変更をなぞり直せば、落ちる直前のコミット済みの状態へたどり着けます。復旧は、いまディスクに残っている本体のデータファイルへ、まだ反映しきれていない分の WAL を継ぎ足し、最新の状態へ組み立て直す形で進みます。 ここで見落としやすい点があります。COMMIT が返っても、本体のデータファイルはその場では書き換わりません。変更が当たったページはいったんメモリ上(共有バッファ)に汚れたページ(dirty page)として残り、ディスクへ確実に書き切られるのは WAL のほうだけです。本体ファイルへの反映は、あとから動くチェックポイントやバックグラウンドの書き出しに任され、状況によっては数分遅れて行われます。コミットのたびに本体のあちこちへ書きにいく遅い動きを避けるための、意図的な後回しです。 図にすると、コミットの瞬間とチェックポイントの瞬間とで、三つの置き場所(メモリ・WAL・本体)の状態はこう食い違います。 この「コミット済みだが本体はまだ古い」という状態は一瞬ではありません。次のチェックポイントまで、ふつうは数秒から数分のあいだ続きます。ただし本当の勘所は「窓が広いから狙わなくてよい」ではなく、そもそも復旧が「どこまで本体へ書けていたか」に左右されない作りだ、という点です。redo は各ページに刻まれた適用済みの位置を見て、まだ当たっていない変更だけを足し直します。だから本体がどれだけ古くても、あるいは一部が先に書けていても、行き着く先は同じコミット済みの状態になります。あとで kill -9 の実験がタイミング合わせ抜きで成立するのは、このためです。 ここで出てくる用語を先に一つだけ紹介しておきます。WAL の中の位置を指す番地を LSN(Log Sequence Number)と呼びます。0/1514378 のように書かれる、ログの先頭からの通し番号だと思ってください。書き込みが進むと LSN は増えていきます。以降の実験は、この LSN が動くのを見るところから始めます。 ...

公開: 2026年7月16日 · Toshihiko Arai
ブザー音源が口の形のフィルタを通ると「あー」という声になる source-filter モデルの図

ノコギリ波が「あー」と歌う ── フォルマント合成

このシリーズでは、サイン波の足し算でノコギリ波を作り 、sin の中に sin を入れてベルやエレピを鳴らして きました。楽器がひととおり鳴るようになると、次に試したくなるのはやはり「声」です。人の声、それも「あ」「い」「う」と聞き分けられる母音を、プログラムで作れるでしょうか。 いかにも難しそうに聞こえますが、実は道具立ては拍子抜けするほど小さくて済みます。ブザーのようなノコギリ波を1本鳴らし、それを2〜3本のフィルタに通す。それだけで、スピーカーから「あー」という声が出てきます。今回はその仕組み、source-filter モデルの話です。 声は「ブザー × 口の形」でできている 声が出る仕組みを、音の流れに沿って追ってみます。まず、のどぼとけの奥にある声帯というひだが、吐く息で高速にパタパタと開閉します。1秒に100〜300回ほどの開閉で、ここで生まれる音を単体で取り出すと、「ブー」というブザーそのものの音です。この開閉の回数が、そのまま声の高さになります。 このブザー音の中身をスペクトル(周波数ごとの成分の一覧)で見ると、基音の整数倍の位置に倍音がずらりと並んでいます。倍音の回 で作ったノコギリ波と、ほとんど同じ姿です。つまり音源としての声帯は、シンセサイザーのノコギリ波オシレータで十分に代役が務まります。 ところで、この時点ではまだ「あ」でも「い」でもありません。母音を作っているのは、声帯の先にある通り道——のど・口・唇までの空間です。管楽器の管がそうであるように、この通り道は特定の周波数で共鳴します。つまり通り道全体が、ある帯域の成分だけを通しやすくするフィルタとして働くのです。舌を動かし、あごを開き、唇をすぼめる。口の形を変えるとは、このフィルタの特性を変えることにほかなりません。 音源(source)はいつも同じブザーで、フィルタ(filter)側の共鳴の山をどこに置くかだけが母音を決める。これが source-filter モデルと呼ばれる、声のもっとも標準的なとらえ方です。この共鳴の山、つまり口の形によって強調される周波数の帯には名前がついていて、フォルマントと呼ばれます。低いほうから F1、F2、F3 と番号を振ります。 このモデルの正しさは、自分の体で確かめられます。声帯を鳴らさずに、ささやき声で「あ、い、う」と言ってみてください。音源がブザーから息のノイズに置き換わっても、母音ははっきり聞き分けられます。母音の情報が音源ではなくフィルタ側、つまり口の形に載っている証拠です。逆に、同じ「あー」のまま音程だけを上下させることもできます。音源の高さとフィルタの形が、それぞれ独立したつまみになっているわけです。 母音を決めるのは、たった2つの数字 フォルマントは F1、F2、F3 と上へ続きますが、母音の聞き分けに効いているのは、実は低いほうの2つだけです。F1 と F2 の周波数の組み合わせが決まれば、母音はほぼ決まります。F3 から上は母音の区別より、声の個人差や質感を担う成分です。 しかも F1 と F2 には、口の動きとの素直な対応があります。F1 は口の開き具合で、大きく開けるほど高くなります。F2 は舌の前後の位置で、舌が前に出るほど高くなります。この2つを軸に取った平面へ日本語の5母音を並べると、こんな地図になります。 「あ」は口を大きく開けるので F1 が高く、地図の上のほうにいます。「い」は口をほとんど閉じて舌を前に出すので、F1 の低い・F2 の高い右下。「お」は口をすぼめるので両方とも低く、左下です。数値はどれも標準的な目安で、実際には話す人の体格や声によって前後しますが、配置の関係はいつもこの形になります。 この地図でいちばん面白いのは、母音が5つの離れた点ではなく、連続した平面の上にあることです。「あ」と「い」の間には、あいまいな中間の母音が地続きに広がっています。実際、「あ」から「い」へゆっくり口を動かしながら声を出すと、声はどこかで切り替わるのではなく滑らかに変わっていきます。地図の上を点が滑っていく——次のデモで、それを指で体験できます。 触ってみる ノコギリ波1本をフォルマントの位置のフィルタに通しただけの、声のデモです。「声を出す」を押すと「あー」と鳴り始めるので、そのまま母音マップの●をドラッグしてみてください。「あ」から「い」へ、途中のあいまいな声を経由しながら滑らかに変わっていきます。マップのどこが何の母音かは、プリセットボタンでも確かめられます。 うまく表示されないときは、デモを別タブで開く 。 鳴らしたまま「声の高さ」のスライダーも動かしてみてください。声は高くなったり低くなったりしますが、「あ」は「あ」のまま変わりません。音源の高さと口の形が別々のつまみだという source-filter モデルの主張そのままの手応えです。スペクトラム表示では、細かく並ぶノコギリ波の倍音の上に、フォルマントの山による起伏が乗っているのが見えます。マップをドラッグすると、この山が横に滑っていきます。 ここでちょっと宣伝を。筆者が個人開発している音感トレーニングアプリ Harmonize でも、「あー」と歌う声の音色をまさにこの方式で試作しています。ノコギリ波を F1=1000 / F2=1400 / F3=3200 Hz のバンドパスフィルタ3本(並列)に通す構成です。開発中の音色なのでいまのアプリにはまだ入っていませんが、本体は音感トレーニングの道具として公開しています。 Harmonize 相対音感と純正律の感覚を鍛える音感トレーニングアプリ 今すぐ無料でダウンロード App StoreGoogle Play どう実現するか 作りは配線図のとおりの素直なものです。今回使うバンドパスフィルタは、指定した中心周波数のまわりの帯域だけを通すフィルタです。フィルタの回 で登場したローパス(低い側を通す)とハイパス(高い側を通す)を直列につないだような特性で、通す帯の中心をフォルマントの位置に合わせれば、そこが共鳴の山になります。音源のノコギリ波を並列に3本のバンドパスへ送り、出てきたものを混ぜるだけです。 ...

公開: 2026年7月16日 · 更新: 2026年7月17日 · Toshihiko Arai
実トロンボーンの録音をFFTで実測して目標数値を立て、合成と再測定のループで音色を当てにいく改良ループの図

トロンボーンの音を「実測」で当てにいく ── 音色工房①

FM合成の回 では、sin 2つから音色の森が生えるという仕組みを見ました。今回は少し毛色を変えて、開発の実録を書きます。テーマは「本物のトロンボーンに寄せる作業を、勘に頼らず測って前に進める工程に変える」ことです。 合成の方式そのもの——倍音の足し算 、FM、ノコギリ波をフィルタで削る減算合成——は、教科書にもこの連載にも書いてあります。ところが方式を知っていることと、実在の楽器の音を当てられることのあいだには、けっこうな距離があります。パラメータの海の中から「トロンボーンのあの音」にたどり着く手順は、教科書にはあまり載っていません。この記事は、その距離をどう詰めたかという作業記録です。 材料は身内から出します。筆者は Harmonize という音感トレーニングアプリを個人開発していて、正解音のガイドとして鳴る楽器音は、録音の再生ではなくすべて自前の合成です。そのラインナップにトロンボーンを足したときの一部始終が、ちょうどこの話の生きた実例になっています。 Harmonize 相対音感と純正律の感覚を鍛える音感トレーニングアプリ 今すぐ無料でダウンロード App StoreGoogle Play 「おとなしい」では直せない 最初に作った版(v1と呼びます)は、いちおうトロンボーンには聞こえました。ノコギリ波をローパスフィルタで丸めた、金管の顔をした音です。ところが実機で鳴らしてみると、感想はひとこと「おとなしい」。本物のトロンボーンが持っている、中低音の張り、音の芯が前に出てくる感じがないのです。 問題は、この感想が改良の役に立たないことです。「おとなしい」から何をどうするのか。フィルタを開く、倍音を足す、音量を上げる——手はいくらでも思いつきますが、どれが正解かは感想からは決められません。勘でつまみをいじり、聴いて、またいじる。これを繰り返しても、良くなったのか悪くなったのかさえ、だんだん分からなくなってきます。耳は「何かが違う」と気づくことにかけては優秀なのですが、どこを・どちらへ・どれだけ直すかを言い当てるのは苦手なのです。 そこで方針を変えました。耳の感想を、測定値に翻訳するのです。 やることは図のとおりで、まず手本になる実物の音を FFT——音の波形を「どの高さの成分がどれだけ含まれているか」に分解する計算——にかけて、目指すべき音の姿を数値のカードにします。あとは自分の合成音も同じ物差しで測り、カードと見比べながらレシピを直していく。目標が数値なので、一手ごとに「近づいたか、遠ざかったか」がはっきり分かります。音色作りが、当てずっぽうから測定のある工学になります。 手本を測って、目標数値を立てる 都合のいいことに、手本はすぐ近くにありました。アプリには効果音として、本物のトロンボーンで演奏された録音がひとつ同梱されています。この録音を FFT にかけて、倍音——基音(音程を決めるいちばん低い成分)の2倍、3倍……の高さで一緒に鳴っている成分——の大きさを測りました。 結果は少し意外なものでした。いちばん大きいのは基音ではありません。第2倍音が基音より 5dB も大きく、第3倍音が基音より 3dB 小さいだけでほぼ肩を並べ、第4倍音が 9dB 落ち。エネルギーの大半は 500〜1000Hz の帯域に集まっていました。トロンボーンの「張り」の正体は、基音の上に乗った中域の倍音たちが主役を張っていることだったのです。 もうひとつ、全体をひとつの数字に要約する指標として、スペクトル重心も測りました。スペクトル重心とは、周波数成分をエネルギーの重みで平均した「音の明るさの重心」で、高い成分が多い音ほど重心は高くなります。フィルタの回 で「高い成分を削ると音がこもる」という話をしましたが、その明るさ・こもり具合を1個の数値で言い表せる物差しです。手本の実測値は約 1.7kHz。こうして目標のカードがそろいました。第2倍音 +5dB、第3倍音 −3dB、第4倍音 −9dB、重心 1.7kHz。ここから先の作業は、この4つの数字を当てにいくゲームになります。 レシピ ── ノコギリ波を3系統に分けて削る 合成の方式には、倍音が全部入ったノコギリ波からフィルタで不要な成分を削り出す、減算合成を使いました。素材のノコギリ波には基音の整数倍の倍音がひととおり含まれているので、あとは「どこを残し、どこを削るか」の設計がそのまま音色になります。 鍵になるのはフォルマントです。フォルマントとは、楽器の管や人の口の形で決まる「よく響く固定の帯域」のことで、音程を変えても動かないのが特徴です。人の声の母音がこれで決まるという話はフォルマント合成の回 に書きましたが、金管楽器も同じで、管とベル(先端の朝顔)の共鳴が特定の帯域をいつも持ち上げています。そこでノコギリ波を3系統に分け、それぞれ別のフィルタを通しました。1系統目は 2.8kHz のローパスフィルタで、音の体になる低域〜中域をそのまま残す「胴鳴り」。2系統目は 620Hz を中心とするバンドパスフィルタ(決まった帯域だけを通すフィルタ)で、手本の主役だった第2倍音のあたりを持ち上げる第1フォルマント。3系統目は 950Hz の第2フォルマントで、第3倍音の張りを受け持ちます。3つを 0.35 : 0.6〜1.0 : 0.7 の重みで混ぜると、目標の倍音バランスの土台ができます。 混ぜたあとに、もうひと味あります。tanh 関数で波形の頭を軽く潰すドライブ(サチュレーション)です。波形の形が変わることは倍音の構成が変わることなので、潰せば潰すほど倍音が増えて音は張り出します。ギターの歪みと同族の現象で、金管の「ブリッ」とした質感はここから出ます。さらに時間方向の演出として、音量は 45ms かけてふわっと膨らみ、明るさ(第1フォルマントの重みとドライブ)はそれより遅い 100ms で開くようにしました。金管のスウェルは音量が先、明るさが後から追いかけてくるからです。おまけに出だしの 10ms だけ、息の当たるノイズ(チフ)を薄く混ぜてあります。音量の輪郭が楽器の顔を決めるという話はエンベロープの回 のとおりで、ここでも効いています。 ...

公開: 2026年7月15日 · Toshihiko Arai
暗い氷青の背景に、粒へ刻まれた波形とマゼンタの固定位置マーカー、氷の結晶、GRANULAR FREEZEの文字を重ねたレコードジャケット風アイキャッチ

音を粒に刻んで凍らせる ── Granular Freeze

「音を止める」と聞くと、波形の再生ボタンを一時停止して、その瞬間の形を静止画のように残す姿を想像します。しかし、スピーカーへ同じ値を出し続けても鳴るのは持続音ではなく、膜が一定の位置へ寄ったままになる直流です。音として聞こえ続けるには、空気を揺らし続けなければなりません。 Granular Freezeが止めるのは波の振動ではなく、音の中を進む再生位置です。流れてくる音を数ミリ秒〜数十ミリ秒の小さな断片、グレイン(grain、音の粒)に刻み、ある一瞬の周辺から取った粒を何度も重ねて鳴らす。同じ場所の波は動き続けるので音は出ますが、次の場所へ読みに行かないので出来事は先へ進みません。音を「連続した波」ではなく「粒の集まり」として扱い直すと、再生位置と時間の進みを切り離せるわけです。 音は数字の列だという連載の起点 から見ると、ここでの操作はバッファに保存した数字をどこから読むか決めているだけです。リングバッファでディレイを作った回 では読み出し位置を一定速度で回しましたが、Granular Freezeではその位置を一点の周囲に留めます。前作のアシッドベース入門 が波形をフィルターで動かす番外編G系列の1本目なら、今回は音の時間そのものを粒へほどく2本目です。 粒の切れ目を窓でなめらかにする グレインを作る最も素朴な方法は、バッファから短い区間をそのまま切り出すことです。ただし、切り出した先頭と末尾の振幅がゼロとは限りません。たとえば波形が0.7のところで突然始まり、別の高さで突然ゼロへ戻ると、スピーカーの位置が一瞬で跳びます。この不連続が広い周波数成分を生み、「プチッ」というクリックノイズになります。 そこで各グレインには窓関数を掛けます。窓関数とは、短い区間の両端をゼロへ絞るための振幅の形です。Hann窓なら、長さ $N$ のグレインの $n$ 番目へ掛ける値は $w(n)=0.5-0.5\cos(2\pi n/(N-1))$。先頭で0から立ち上がり、中央で1になり、末尾でまた0へ戻ります。 窓を掛けると切れ目は消えますが、1粒だけでは両端が無音になります。そこで次の粒を少し早く始め、窓の山どうしを重ねます。粒の長さを表すgrain sizeを短くすると、凍結位置の細かな質感を拾いやすく、金属的で粒立った音になりやすい。長くすると元の音程や声らしい響きが残りやすい一方、元の時間変化も少し抱え込む。この数十ミリ秒の選び方が、静止した音の輪郭を決めます。 密度を上げると粒が連続音になる 1秒あたりに鳴らすグレイン数をdensity(密度)と呼びます。密度が低く、前の粒が消えてから次が始まる状態では、耳は一つひとつを「プッ、プッ」と分かれた音として追えます。密度を上げて複数の窓が重なると、どれかの粒が常に鳴っている状態になり、粒の列は切れ目のない持続音へ変わります。この重なりがオーバーラップです。 密度は多ければ多いほどよいわけではありません。同時に鳴る粒が増えると振幅も足し合わされるので、音量をそのままにするとクリップします。実装では重なり数に応じて各グレインのゲインを下げるか、出力側で余裕を持たせます。密度が低い領域では粒のリズムが、高い領域では滑らかな面が聞こえる。この点から線、線から面への変化が、グラニュラー処理の面白さです。 位置とピッチを散らすと音の雲になる 凍結位置を完全な一点に固定すると、まったく同じ断片が同じ周期で並びます。素材によっては規則性が耳につき、短いループのような「ブーン」という癖が出ます。そこで位置へごく小さなランダム幅を足します。position jitter(位置ジッター)とは、基準位置の前後からグレインの開始点を少しずつ選び直すばらつきです。 さらに各グレインの再生速度をわずかに変えるpitch spread(ピッチの散らばり)を加えると、粒ごとに音程が少しずつずれます。中心となる音は残しながら、同じコピーばかりが重なる規則性をほどけます。 これは空間の反射を写し取って残響を作る畳み込みリバーブ とは違う方向の質感作りです。畳み込みが部屋の応答で音を包むのに対し、Granular Freezeは音そのものを多数の小片へ分け、時間とピッチのばらつきで雲へ組み替えます。jitterを広げすぎれば元の瞬間から離れ、pitch spreadを広げすぎれば音程の芯が消えるので、自然なフリーズには「固定点の周囲をほんの少し曇らせる」程度が効きます。 Freezeという技法はどこから来たのか 音を粒として捉える考えは、デジタル音響より古く、1946〜47年に物理学者デニス・ガボールが提示した音響学的量子理論まで遡ります。音を微小な時間と周波数を持つ粒の集まりとして記述する理論でした。1959年には作曲家ヤニス・クセナキスが、録音テープをはさみで細かく切って貼り直すという物理的な方法で、手作業のグラニュラー合成を実現します。 1975年、カーティス・ローズはグラニュラー合成を初めてコンピュータ上で実現しました。計算機の中なら、粒の位置、長さ、密度、ピッチを大量に制御できます。ローズは2001年の著書『Microsound』で、この音符より小さな時間領域の理論、歴史、作曲技法を体系化しました。 エフェクトとしてのFreezeを考えるうえで重要な実例が、フランスの電子音響音楽研究機関GRMに由来するGRM ToolsのFreezeです。約30秒のバッファへ音を取り込み、その中の一区間を指定して、ループ、重ね合わせ、ピッチシフトをしながらリアルタイムに動かせます。内部ではバッファを数サンプル単位までグラニュラー化して重ね、時間を留める効果を作ります。GRM Toolsの原型はユーグ・ヴィネが作り、1994年以降、エマニュエル・ファヴローらによってプラグイン化されました。FreezeやShufflingは、今日のグラニュラー系エフェクトへつながる源流のひとつです。 現在の制作環境にも同じ考えはあります。Ableton Live標準のGrain Delayは、入力を小さな粒として取り込み、指定時間後に粒ごと再生するエフェクトです。Frequencyがgrain sizeをHzで表し、ピッチシフトや時間・ピッチのばらつきを調整できます。AbletonのGranulator(Max for Live)は、サンプルを短い断片に分け、重ね合わせとクロスフェードで再生するグラニュラーシンセサイザーです。道具の名前や目的は違っても、「どこから粒を取り、どのくらい重ね、どれだけ散らすか」という設計は共通しています。 録音で聴くフリーズの質感 道具の話が続いたので、最後に「この質感を丸ごと聴かせてくれる音楽」を少しだけ紹介します。グラニュラー・フリーズは、前回のTape Stop のAvicii「Levels」のように誰もが知るヒット曲の決め技になっているわけではありません。むしろ音を細かい粒に崩して時間を宙づりにする、その手触りそのものを味わうタイプの音楽で生きます。下の2枚は、まさに「粒の雲」が作品まるごとに広がっている代表格です。 坂本龍一 / 2017 async 晩年の坂本龍一が、ピアノや環境音を断片的・粒状に扱ってつくったアルバム。音が一点で漂ってなかなか前へ進まない場面が随所にあり、日本の耳になじみのある入口としても聴きやすい一枚です。 YouTubeで探す Amazonで探す Fennesz / 2001 Endless Summer ギターの音をノートパソコンで粒に砕き、真夏の光のような音の雲へ組み替えた一枚。この記事で作った「固定点の周囲をほんの少し曇らせる」質感が、そのまま一続きの音楽として立ち上がっているのが聴けます。 YouTubeで探す Amazonで探す ジャケット画像はMusicBrainz / Cover Art Archive由来の画像を記事内に同梱して配信しています。 ...

公開: 2026年7月15日 · Toshihiko Arai