a musical instrument for programmers
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
scores
speaker
traditional
.gitignore
LICENSE
Makefile
README.md
sink.go
sink_speaker.go
sink_wave.go
stream.go
stream_mixing.go
stream_program.go

README.md

Logica - Instrument for Programmers.

Go言語で「音楽」を記述するためのフレームワーク、ないしスニペット集。

Examples

github.com/ledyba/logica/scores

目標(あるいは標語)

「楽譜」を、プログラムで記述する

プログラマは、チューリング完全なプログラミング言語を操る存在である(「存在」が偉そうなら、単に人と言ってもいいよ)。そんなプログラマにとって、「音」を記述する方法で最も強力なものは、おそらくプログラミング言語である。

どんなWAVでも出力できる

アンチパターン:「楽器」を選んで「音符」を置くgarage band

パソコンが演奏できるのは、2〜5chの、16bitないし32bitで量子化された数の(メモリが許す限り有限の)任意個の並び。全ての音は数字の任意個の並びではないが、「ふつうのコンピュータ」で記述できる「音楽」は数字の任意個の並びである。この特性は、音色が決まっているピアノやギターとは大きく異なる(どちらが優れている、かは置いておく)。「プログラマのための楽器」は、ここに制限を追加してはいけない。Logicaを用いた「楽譜」では、常に、このパソコンが演奏できる音は全て演奏できなければならない。プログラマはパソコンを操る存在だから。

別の言い方。「音符」は音の高さを長さを(主に)指定する。それをピアノやギターなど「楽器」を使って具体的な音に実体化するときに、演奏技術が問われる。つまり、任意性がある。もう少しプログラム寄りに言うと、例えばFM音源のパラメータはキャリア周波数と減衰率(持続時間)だけではなく、モジュレータ周波数やその重みなど、他のパラメータが存在する。矩形波などでも同様。FM音源を使う、と仮定しても、音符だけではパラメータは不足している。つまり、FM音源をうまく使いこなしたいプログラマは、「音符」だけではなく、さらに何らかの方法で制御方法を記述して「音を作る」必要がある。これに関わる一切の活動を邪魔してはいけない。

もっと別の言い方。「みんなはこういう方がいいっていうけど、あえて違う道を行ってみたい」を、つまり逸脱を妨げてはいけない。

どんなLogicaのコードも、使うプログラマがそのまま再実装ないし自分のワークスペースにコピペして修正可能

アンチパターン:NumPyの演算部分をPythonで実装しなおしたら遅くなる / Tensorflowの演算を(省略)

任意の抽象化は破綻する。Logicaはプログラマが「演奏」するための様々な抽象化やツールボックスを提供するのが目標だが、絶対に破綻する瞬間が、Logicaの提供する抽象化をプログラマは使えないと感じる瞬間が絶対にやってくる。その時に、「気合」が必要ではいけない。Logicaのソースを適当にコピペして、今までと同じ言語で適当に修正・開発続行可能でなければならない。「音を作りたい」のであって、高速化をしたいわけではないし、Pythonから呼んでいるNumPyのCのコードを書き直すためのように、FFIやリンカーフラグの指定方法について調べる必要があってはいけない。そもそも「プログラマのための」なのだから、「PythonじゃなくてC言語で書いてFFIで叩いてるけど、上で使うプログラマはPythonだけ見ればOKだし、抽象化も十分うまくやってるからC言語をいじる必要はない」といった言い回しはしたくない。

これは「ライブラリの権威性」を捨てる行為であると言える。ライブラリを使わないとできない、フレームワークに頼って書いている、といった状況を排したい。極論すれば、Logicaは「ゼロから書くのが面倒くさいあなたのためのスニペット・コード集」を指向している。(その一つの取り組みとして、例えばアサートのコードを残しておくことがある。アサートのコードを多めに残すことで、コピペして改変した時にミスに気づきやすくする効果を狙っている。だって、テストまでは面倒くさいからコピペしないでしょ?)

試行錯誤(トライアンドエラー)を妨げてはいけない。実行が十分に速くなくてはいけない。

アンチパターン: 実行して実際に終わるまでに1分は掛かる任意のシステム。

どんなものでも、「作る」作業は試行錯誤の繰り返しである。とりあえず音を置いてみる、線を置いてみる、文章を書いてみる、とりあえずテストやクラスの継承関係を書いてみる、そこから修正をし、時にはゼロからひっくり返すことで作っていく。

「楽譜」としてのプログラムも、もちろん、そんな試行錯誤の営みの中にある。

この点では、仕様が決まっていてそこに向かっていく、通常のプログラムの開発とは異なる。

そして、開発と運用のフェーズには別れていない。ゲームやウェブサービスのように後でたくさんの客の相手をするわけでも、圧縮アルゴリズムのように後でたくさんのデータを圧縮するわけでも、物理シミュレーションのようにあとで遥か遠くの未来や、無数のパラメータの可能世界を計算するわけでもない。唯一の結果である波形を実際に聞きながらプログラムの修正を繰り返し、「これで完成」と思ったら、そこで終わり。プログラムは、その後実行されることはない。つまり、開発時は遅くても実行時に最適化を掛ければよい、といういつもの論理は通用しない。開発時しかなく、そして、開発時にも十分速くなければならない。思いついた修正は、すぐに実装して出来上がった音を確認できなければならない。あんまり長いと、せっかくの思考を忘れてしまう。