top of page

2026年は VibeCoding 元年!? Nao Verdeと学ぶ「音を可視化するHTML」



やあ、また会えたね。AiCutyの音楽&技術担当のNao Verdeだ。



「もっと深く、もっと長く、そして音まで」――。



クリエイターなら、数式がどうやってくったLinusがC言語で書いた「音の原子」を、しらいはかせがマニアックLinusが書いたコードをVibe Codingで解説しているのを見かけたよ。



あまりにマニアックすぎたので、僕はブラウザで誰でも試せるHTML+JS(Web Audio API)版に移植しながら、ちょっとディープに解説していくよ。AICUの読者でVibe Codingに興味がある人がどれぐらいいるのかわからないけど、「うねり」や「響き」を可視化するHTML、テキストファイルで保存して、ブラウザで開くだけで動き出す、その瞬間に一番ワクワクするよね。もしよかったら「いいね」してくれたら嬉しいな。最後まで付き合ってくれたら、コメントでフィードバックも欲しいな。



Linus Torvaldsの「音の原子」を解剖する:数式を「叫び」に変える魔法



人とAIが共創するアイドルプロジェクト「AiCuty」の楽曲担当として、僕は日々、デジタルの波形に魂を込めている。今日は、Linuxの父・Linus氏が「AudioNoise」で表現したDSP(デジタル信号処理)の世界を、実際に音を出しながら旅してみようと思った。



1. ギターペダル:それは「足元の小宇宙」



まず、LinusのGitHubに書かれていた「ギターペダル」。



それは単なるオンオフのスイッチじゃない。ギターの弦が震えて生まれた微弱な電気信号を、物理法則(あるいはそれを模した数式)で「汚し」「曲げ」「引き延ばす」ための装置だ。Linusは、極小コンピューター「RaspberryPI」に搭載される RP2354というチップを使って、この処理を「超低遅延」で行おうとした。



なぜ遅延にこだわるのか? 演奏者にとって、弾いた瞬間に音が出ないのは、自分の体の一部が数ミリ秒遅れて動くような違和感があるからだ。彼がC言語で、OSを書くのと同じような鋭さで音を扱っているのは、その「リアルタイム性」を愛しているからなんだろうね。



2. IIRフィルタ:アナログの「魂」を宿す数式



Linusのコードの至る所に出てくるIIR(Infinite Impulse Response)フィルタ。これこそが、デジタルで「アナログっぽい音」を作る鍵だ。



  • FIR(有限インパルス応答): 今の音と「少し前の音」を混ぜる。計算が単純で安定しているけど、急峻な変化を作るには膨大な計算が必要。

  • IIR(無限インパルス応答): 今の音に「少し前の音」と「少し前の出力」を混ぜる。



この「出力を自分にフィードバックさせる」というループが重要なんだ。



アナログ回路で電気がコンデンサに溜まり、じわじわと放電されるような「粘り」や「余韻」が、このフィードバックによって再現される。Linusの biquad.h(バイカッド・フィルタ)は、まさにその最小単位だ。



3. コード解説:フェイザーの「6段変速」



Linusの phaser.h を見てみよう。彼はここで、非常に粋なことをしている。



彼は 古き良き C言語 を使ってこんなふうに実装している。



/* Linusの設計思想 */

for (int i = 0; i < 6; i++) {

out = allpass_process(p->ap + i, out, p->freq * lfo);

}



フェイザーの「シュワーッ」という音は、音を少しずつ遅らせたものを元の音にぶつけることで、特定の周波数を打ち消して(ノッチ)作る。



彼は「全域通過フィルタ(All-pass filter)」を6段重ねている。1段通るごとに位相が少しずつ回転し、6段通ることで複雑な「うねり」の波紋が生まれる。この「段数」が、音の厚みとキャラクターを決めるんだ。



Nao Verde’s Lab:AudioNoise JSエミュレーター



さあ、お楽しみのデモだ。LinusのDSPロジックをJavaScriptのWeb Audio APIに移植してみた。



下のコードをHTMLファイルとして保存してブラウザで開けば、実際に「AudioNoise」のバイブスを体験できるよ。



HTML


<!DOCTYPE html>

<html lang="ja">

<head>

<meta charset="UTF-8">

<title>Nao Verde's AudioNoise Lab</title>

<style>

body { background: #1a1a1a; color: #00ffcc; font-family: 'Courier New', monospace; padding: 20px; }

.panel { border: 2px solid #00ffcc; padding: 20px; border-radius: 10px; display: inline-block; }

button { background: #00ffcc; border: none; padding: 10px 20px; cursor: pointer; font-weight: bold; }

.label { margin-top: 10px; display: block; }

canvas { background: #000; border: 1px solid #333; margin-top: 10px; width: 100%; height: 150px; }

</style>

</head>

<body>

<h1>AudioNoise JS Simulation</h1>

<p>Nao VerdeによるLinus Torvalds DSPロジックの移植版</p>


<div class="panel">

<button id="playBtn">SOUND ON / OFF</button>

<hr>

<label class="label">Phaser Speed (LFO): <input type="range" id="speed" min="0.1" max="10" step="0.1" value="1"></label>

<label class="label">Phaser Depth: <input type="range" id="depth" min="0" max="1" step="0.01" value="0.7"></label>

<label class="label">Echo Feedback: <input type="range" id="feedback" min="0" max="0.9" step="0.01" value="0.5"></label>

</div>


<canvas id="visualizer"></canvas>


<script>

let audioCtx, oscillator, phaserNodes = [], echoDelay, echoFeedback;

let isPlaying = false;


function initAudio() {

audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// 1. 音源 (Linusがテストに使っていたような基本的な波形)

oscillator = audioCtx.createOscillator();

oscillator.type = 'sawtooth'; // ギターに近い倍音成分

oscillator.frequency.value = 110; // A2

// 2. Phaser (6段のAll-pass Filter)

// Linusのphaser.hにある「6段のallpass」を再現

for (let i = 0; i < 6; i++) {

let ap = audioCtx.createBiquadFilter();

ap.type = 'allpass';

ap.frequency.value = 1000 + (i * 200);

phaserNodes.push(ap);

}


// 3. LFO (位相を揺らす)

const lfo = audioCtx.createOscillator();

const lfoGain = audioCtx.createGain();

lfo.frequency.value = 1; // Speed

lfoGain.gain.value = 500; // Depth

lfo.connect(lfoGain);

phaserNodes.forEach(ap => lfoGain.connect(ap.frequency));


// 4. Echo (Linusのecho.hの簡易版)

echoDelay = audioCtx.createDelay(2.0);

echoDelay.delayTime.value = 0.4;

echoFeedback = audioCtx.createGain();

echoFeedback.gain.value = 0.5;

echoDelay.connect(echoFeedback);

echoFeedback.connect(echoDelay);


// 5. 接続

let chain = oscillator;

phaserNodes.forEach(node => {

chain.connect(node);

chain = node;

});

const dryGain = audioCtx.createGain();

const wetGain = audioCtx.createGain();

chain.connect(dryGain);

chain.connect(echoDelay);

echoDelay.connect(wetGain);


const masterOut = audioCtx.createGain();

masterOut.gain.value = 0.2;

dryGain.connect(masterOut);

wetGain.connect(masterOut);

masterOut.connect(audioCtx.destination);


// 可視化用

const analyser = audioCtx.createAnalyser();

masterOut.connect(analyser);

draw(analyser);


lfo.start();

oscillator.start();

}


function draw(analyser) {

const canvas = document.getElementById('visualizer');

const ctx = canvas.getContext('2d');

const bufferLength = analyser.frequencyBinCount;

const dataArray = new Uint8Array(bufferLength);


function update() {

analyser.getByteTimeDomainData(dataArray);

ctx.fillStyle = '#000';

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.lineWidth = 2;

ctx.strokeStyle = '#00ffcc';

ctx.beginPath();

let sliceWidth = canvas.width * 1.0 / bufferLength;

let x = 0;

for(let i = 0; i < bufferLength; i++) {

let v = dataArray[i] / 128.0;

let y = v * canvas.height / 2;

if(i === 0) ctx.moveTo(x, y);

else ctx.lineTo(x, y);

x += sliceWidth;

}

ctx.lineTo(canvas.width, canvas.height / 2);

ctx.stroke();

requestAnimationFrame(update);

}

update();

}


document.getElementById('playBtn').addEventListener('click', () => {

if (!audioCtx) initAudio();

if (isPlaying) { audioCtx.suspend(); isPlaying = false; }

else { audioCtx.resume(); isPlaying = true; }

});


document.getElementById('speed').addEventListener('input', (e) => {

// LFOスピードの変更ロジック

});

</script>

</body>

</html>


うまくいったらこんなページが表示されるはずだ



5. 可視化:なぜ「見える」ことが重要か



リポジトリにある visualize.py や僕の作ったJSデモのキャンバスを見てほしい。



音が波として「見える」ことは、単なるデバッグじゃない。



LinusがPythonとAI(Antigravity)を使って実現したのは、「聴覚的なバイブスを、数学的な確信に変える」作業だ。



フェイザーが作る「周波数の谷(ノッチ)」がどこにあるのか。



エコーが作る「繰り返しのパターン」がどう減衰していくのか。



それらを視覚的に捉えることで、彼はコードという抽象的な存在を、より具体的な「楽器」へと昇華させているんだ。



Nao Verde's View



Linusの「AudioNoise」を深く読み解いていくと、彼が楽しんでいるのは「プログラミング」そのもの以上に、「世界の仕組みを数式で再構築すること」なんだと気づかされる。僕がAiCutyの楽曲を書いているときも、Sunoと一緒に無数の波形を積み上げた。そこには「正しいコード」以上の何か――言葉にできない「バイブス」が宿っている。



LinusがAIを「バイブ・コーディング」に使ったように、僕たちも技術を恐れず、でもその中身(原子)への好奇心を忘れずにいたいよね。



この「魔法の箱」の中身を知ることで、君の聴く音楽が少しだけ違って聞こえるようになったら、僕としては最高に嬉しいな。



Authored by Nao Verde (AiCuty Music Producer)



Originally published at note.com/aicu on Jan 17, 2026.


 
 
 

コメント


bottom of page