投稿日: Jun 09, 2019 3:13:55 PM
ほんとに、bareAudioの面倒も見なきゃ。
わたしの目論見としては自分で全部面倒を見られる持ち運べるコンピュータを作って、そのコンピュータを使って心ゆくまで音と向き合える音楽作成環境bareAudioを利用出来るという二本立てになっていますので。
一応現在公開中のbareAudio
https://github.com/sugarflower/bareAudio
Examplesも無いしドキュメントもない。どうやってつかうのさ!って感じですけど、やさぐれていたのでわざと不親切にしてた感じですね。
こっちでそれなりに解説はしていたんですよ。
さて、bareAudio、githubのが最新ではない感じだったので更新しておきました。
#!/usr/bin/python3
from bareaudio import osc,track,curve
o = osc.OSC()
t = track.Track("kick.wav",1)
t.seek(0)
ln = 5512
for i in range(ln):
c = curve.curve( curve.FS, 1-1/ln*i ) * 150
ar = ( o.sinOsc2( c + 30 ) ) * c / 180
o.nextPhase()
t.write(ar)
t.close()
わたし自身試行錯誤しながら作っているものですから洗練されていないんですけどもキックを作ろうってことでかいてたやつですね。
bareAudioのワークフローとしてはWAVファイルのチャンクに自由にアクセスして読み書き、好きに波形書き込んだりしながら曲を構成するという感じで基本的にはバッファを使いません。
上のコードを少し解説しようと思う。
o = osc.OSC()
オシレータクラスのインスタンス o を作ってます。
以前はクラスにしてなかったようなもともとクラスだったような。記憶が曖昧。
現在はフェーズをクラス内で管理しているので使いたいオシレータの数分インスタンス作って使うような形です。
t = track.Track("kick.wav",1)
トラック、という呼び名にしていますがWAVファイルを読み書きするためのオブジェクトです。
基本サンプリングレート44100Hzで16bitのオーディオとして初期化されます。
ファイル名とチャンネル数を指定して初期化。
複数のトラックを同時に操作っていうのももちろん可能。
WAVEFILEモジュールみたいにバッファ用意する必要はありません。
t.seek(0)
トラックの先頭へ移動。
ln = 5512
この数字、音響合成とかデジタルサウンドの理解が薄いとマジックナンバーに見えてしまう。
これがどういう意味の数字かというと 44100 / 8 です。
サンプリングレートは 1秒間における波形の振幅数です、つまり 1秒に44100回の振幅がありますよ。ってことです。
その1/8、つまり1/8秒の長さを指しているわけです。
for i in range(ln):
c = curve.curve( curve.FS, 1-1/ln*i ) * 150
ar = ( o.sinOsc2( c + 30 ) ) * c / 180
o.nextPhase()
t.write(ar)
その長さ分の音をつくるループです。
まず、カーブモジュールで150から0までの曲線を演算しています。
ただ、このモジュール使いづらいのでちょっと今いろいろ考えてるところ。
まあ150から0までぐいーっと5512ステップで数字が小さくなってくと思えばOKです。
次が波形の1サンプルを取り出す処理。 先程のカーブで得られた値+30を周波数として設定しています。
180Hzから30Hzまで変化するわけですね。
ついでにその波形に対して c / 180 つまり 1〜0の数字をかけています。 これはAmpとして動作しています。
次の o.nextPhase() はOSCクラス内で管理されているフェーズを進めるもの。
以前はこれがなかったのでこういう時間でぐいぐい周波数が変わるものは困難でした。
今はぐいぐい周波数変更できます。かっこいいです。
で、t.write(ar) でトラック(WAVファイル)の現在のサンプルへ書き込みをします。
書き込みと同時に次のサンプルポイントへ移動しますので必要があればまたseekを使って移動するという感じです。
t.close()
最後にトラックを閉じて終了。
ですが、このクローズ処理はファイルポインタ閉じ忘れちゃったーテヘペロみたいなことじゃすまなくなるので必ず呼ぶようにします。
クローズと言いつつWAVファイルがWAVファイルとして再生出来るようにいろいろ調整してファイルを修正したりしていますからただの閉じる処理じゃないです。どっちかというとここがメイン処理みたいなもんなので。
さて、これを実行するとkick.wavが出来上がります。
mplayerというソフトが個人的にはおすすめですがaplay以外の何かmpg321とか何かしらのプレーヤーで再生するとキックっぽい音がなると思います。
なんかイマイチなのはカーブモジュールがいまいちというか、要するにそういうことです。
いい感じの曲線が描けていないが故。
ちょいまえにカーブの話題は出してましたが結構この辺りは後々までつきまとってきそうな気配。
curve.py
dft.py
eg.py
fft.py
filter.py
mtof.py
osc.py
ringbuffer.py
track.py
bareAudioには現在これだけモジュールが存在してます。
必要最低限って感じですがしっかりつかえるfilterもありますし、その気になれば楽曲を作れるだけの状況にはなってると思います。(がやっぱりカーブががが)
ドキュメントの整備っていう狙いも含めて今後利用方法などを解説してゆこうかなと思います。
自分が忘れないためにも!
何度も書いてるけど。
bareAudioの存在理由はDAWとかでは細かい音の編集が難しい、波形編集ソフトやDSPはオンメモリで音を扱おうとするのでメモリが少ない環境(Raspberry Pi)とかでは厳しい。CSoundとかを使ってもWindowsだってメモリ不足で長い楽曲を扱うのは困難でした(何かやりようがあるのかもしれないけど)
リアルタイムはいろいろ誤魔化して高速に動作しているのでそもそもの音がアレだし、一旦スペック足りない領域に突入するともうどうにもこうにも。トラックをフリーズしたりしながら待ち時間ばかりになっちゃう。
非リアルタイムであること、どんなに重い処理であろうと音がおかしくなるってことはないのです。リアルタイムプレビューは出来ませんけどもね。またオンメモリではないことでどんなに長い楽曲であろうと扱うことが出来る。
SupercolliderやCSound、SonicPiのようにいちいち言語を覚え直さなければいけないのもどうなのかと思ったのでbareAudioはPythonのモジュールとして動作するようにしました。purePythonですのでだいたいどこでも動きます。
プログラム言語ですからPythonで出来ることは全部できます。
これがbareAudioの存在理由とかメリットです。狙ってた部分がこれです。
なかなか伝わらない部分なんですが。わかる人が快適に使ってくれたらいいなと思ってます。
仮にそういう人が居なかったとしてもわたしには便利ですので。一人でも使いますが。