Posted at

Node で Axel F(Beverly Hills Cop Theme)を奏でてみた

More than 5 years have passed since last update.


はじめに

この記事は Node AdventCalendar 13 日目の記事です。

Node.js Advent Calendar 2013

はじめは MVC フレームワークの Geddy について書こうと思ったんですが、あまり触れなかったので、シンセっぽいことができる baudio で遊んだので、それの紹介をしたいと思います。


baudio

baudio で遊ぶ前に sox を入れておきましょう。

sox は HomeBrew からインストールできますよ。

$ brew update

$ brew install sox

次に baudio をインストールします。

$ npm install baudio -g


簡単な使い方

baudio にはメソッドの説明は書かれていますが、どんな処理を書けばどんな音が出るのかが説明はされていません。

Youtube に若そうなのにひげもじゃな人が解説してくれている デモンストレーション があるので、そちらを御覧ください。

僕はよくわかっていません…

var baudio = require('baudio');

var b = baudio();

b.push(function (t) {
return Math.sin(t * 400 * Math.PI * 2) + Math.sin(t * 500) * (t % 2 > 1);
});

b.play();

example の一つですが、周期的に2つの音を鳴らすパターンです。このように push のコールバックに処理を書くことで様々な音を鳴らすことが出来ます。また、push を複数呼び出すことで同時に別の音を出力可能です。

他にもサンプルがあるので参考にしてみてください。


ビバリーヒルズ・コップのテーマを奏でる

残念ながら細かい説明は出来ませんが、いろいろ頑張ってビバリーヒルズ・コップのテーマである「Axel F」を演奏することにしました。

ソースコードを…といいたいところですが、さすがに出力されるものが音なので、ソース見ただけではさっぱりだとおもいます。

ですので、再生の様子を Youtube にアップしたのでそちらをごらんください。

Axel F with Node.JS -YouTube

というかんじでエディ・マーフィーもビックリですね。では最後にソースを貼っつけときます。一応 github にも上げているので、fork して誰か続きを奏でてみてください。

astronaughts/AxelF

var baudio  = require('baudio'),

b = baudio();

var melody = [
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,

1400, 0, 0, 0,
1700, 0, 0, 1400,
0, 1400, 1900, 1900,
1400, 0, 1250, 0,

1400, 0, 0, 0,
2100, 0, 0, 1400,
0, 1400, 2250, 2250,
2100, 0, 1700, 0,

1400, 0, 2100, 0,
2800, 0, 1400, 1250,
0, 1250, 1050, 0,
1600, 0, 1400, 1400,

1400, 1400, 1400, 1400,
1400, 1400, 1400, 1400,
0, 0, 0, 0,
0, 0, 0, 0,

1400, 0, 0, 0,
1700, 0, 0, 1400,
0, 1400, 1900, 1900,
1400, 0, 1250, 0,

1400, 0, 0, 0,
2100, 0, 0, 1400,
0, 1400, 2250, 2250,
2100, 0, 1700, 0,

1400, 0, 2100, 0,
2800, 0, 1400, 1250,
0, 1250, 1050, 0,
1600, 0, 1400, 1400,

1400, 1400, 1400, 1400,
1400, 1400, 1400, 1400,
0, 0, 0, 0,
0, 0, 0, 0,
];

var base = [
700, 0, 0, 0,
1400, 0, 0, 630,
0, 1250, 520, 520,
1050, 0, 630, 0,

700, 0, 0, 0,
1400, 0, 0, 0,
0, 630, 1050, 1050,
1250, 0, 1400, 0,

550, 0, 0, 0,
1100, 0, 0, 630,
0, 1250, 630, 630,
630, 0, 700, 0,

1400, 1400, 1400, 1400,
0, 0, 0, 0,
0, 1250, 1050, 0,
950, 0, 850, 0,

700, 0, 0, 0,
1400, 0, 0, 630,
0, 1250, 520, 520,
1050, 0, 630, 0,

700, 0, 0, 0,
1400, 0, 0, 0,
0, 630, 1050, 1050,
1250, 0, 1400, 0,

550, 0, 0, 0,
1100, 0, 0, 630,
0, 1250, 630, 630,
630, 0, 700, 0,

1400, 1400, 1400, 1400,
0, 0, 0, 0,
0, 1250, 1050, 0,
950, 0, 850, 0,

700, 0, 0, 0,
1400, 0, 0, 630,
0, 1250, 520, 520,
1050, 0, 630, 0,

700, 0, 0, 0,
1400, 0, 0, 0,
0, 630, 1050, 1050,
1250, 0, 1400, 0,

550, 0, 0, 0,
1100, 0, 0, 630,
0, 1250, 630, 630,
630, 0, 700, 0,

1400, 1400, 1400, 1400,
0, 0, 0, 0,
0, 1250, 1050, 0,
950, 0, 850, 0,
];

// melody part
b.push(function (t, i) {
var f = melody[Math.floor((t * 8) % melody.length)];
return Math.tan(t * Math.PI * (f / 4));
});

// base part
b.push(function (t, i) {
var f = base[Math.floor((t * 8) % base.length)];
return Math.tan(t * Math.PI * (f / 16));
});

b.play();