コンピュータやソフトウェアのあれこれ@道民(&元道民)
Posts tagged all
Web Audio APIはじめました
10月 25th
(function () {
var ctx = new webkitAudioContext();
//console.log( ctx );
var dst = ctx.destination;
//console.log( dst );
var buf = ctx.createBuffer( 1, 4096 * 4, ctx.sampleRate );
var data = buf.getChannelData( 0 );
for (var i=0; i<data.length; i++) {
data[i] = ( i % Math.floor(44100 / 440) );
}
console.log( data );
var src = ctx.createBufferSource();
//console.log( src );
src.buffer = buf;
src.connect( dst );
src.noteOn( 0 );
})();
なんか分かんないけど、こんな感じのコードで音が鳴った。
Canvasのように、まずcontextを取得するのは分かる。
W3CのAPIリファレンスを見ると、contextでいろいろ生成するみたい。
よく分かんないのでconsole.log()を使って、
何が入ってるのかChromeで確認しながら作業した。
(こういうとき英語読めたらいいなーって思う。)
とりあえず、エラーが出ないように、見よう見まねでコードを書いて、
きっと波形を入れればと思って、それっぽく初期化したら音が出た。
あと、Chromeでテストしてるけど、Chromeごと落ちることがあるらしく、
自分も1回落ちたけど、再現性はない。
下手なコードを書いたからとかじゃないらしい。
早くループさせたりフィルターをいじってみたいけど、
perlも待ってるのでバランス良くやる方向で。
おしまい。
10/26 追記
MacBookAirでスリープ解除してから
このスクリプト実行したらChromeごと落ちて、
そのあとは普通に音が鳴ったので、
このスクリプトは良くないのかも知れないです。
[perl][perl+web][math]Directing AE with Arrows
10月 23rd
@maki_daisukeさんに教えてもらったのを読んで実装してみた。
use strict; use warnings; { package AsyncArrow; use Scalar::Util qw/weaken/; use AnyEvent; use Exporter qw/import/; use Class::Accessor::Lite new => 1, rw => ['code']; our @EXPORT = qw/repeat done/; sub repeat_request(;$) { {repeat => 1, value => shift} } sub done_request(;$) { {done => 1, value => shift} } sub arr { my ($class, $f) = @_; $class->new(code => sub { my ($v, $progress, $cont) = @_; $cont->($f->($v), $progress); }); } sub compose { my ($self, $other) = @_; return (ref $self)->new(code => sub { my ($v, $progress, $cont) = @_; $self->code->($v, $progress, sub { my ($v, $progress) = @_; $other->code->($v, $progress, $cont); }); }); } sub run { my ($self, $v, $progress) = @_; $progress ||= ProgressArrow->new_without_args; $self->code->($v, $progress, sub { my ($v, $progress) = @_; return; }); return $progress; } sub repeat { my $self = shift; my $weaken_loop; my $loop = sub { my ($v, $progress, $cont) = @_; $self->code->($v, $progress, sub { my ($v, $progress) = @_; if ($v->{repeat}) { my $canceller; my $t = AE::timer 0, 0, sub { $progress->advance($canceller); $weaken_loop->($v->{value}, $progress, $cont); }; $progress->add_canceller($canceller = sub { undef $t }); } elsif ($v->{done}) { $cont->($v->{value}, $progress); } else { die } }); }; weaken($weaken_loop = $loop); (ref $self)->new(code => $loop); } } { package ProgressArrow; use parent qw/-norequire AsyncArrow/; use Scalar::Util qw/weaken/; use Class::Accessor::Lite rw => ['cancellers', 'observers']; sub new_without_args { my $class = shift; my $self = $class->new( cancellers => [], observers => [], ); weaken(my $weaken_self = $self); $self->code(sub { my ($v, $progress, $cont) = @_; push @{$weaken_self->observers}, sub { my ($v) = @_; $cont->($v, $progress); }; }); return $self; } sub add_canceller { my $self = shift; push @{$self->cancellers}, @_; } sub advance { my ($self, $canceller) = @_; @{$self->cancellers} = grep {$canceller != $_} @{$self->cancellers}; while (my $observer = shift @{$self->observers}) { $observer->(); } } sub cancel { my ($self, $canceller) = @_; while (my $cancel = shift @{$self->cancellers}) { $cancel->(); } } } use AnyEvent; use AnyEvent::Handle; sub inputted_line() { AsyncArrow->new(code => sub { my ($v, $progress, $cont) = @_; my $canceller; my $hdl = AnyEvent::Handle->new( fh => \*STDIN, on_error => sub { my ($hdl, $fatal, $message) = @_; $hdl->destroy; $! and warn "$message(fatal=$fatal)"; $cont->(); }, on_read => sub { my ($hdl) = @_; $hdl->push_read(line => sub { my ($hdl, $line, $eol) = @_; $progress->advance($canceller); $canceller->(); $cont->($line, $progress); }); }, ); $progress->add_canceller($canceller = sub { undef $hdl }); }); } my $cv = AE::cv; my $total_length = 0; my $p = inputted_line->compose(AsyncArrow->arr(sub { if (defined $_[0]) { $total_length += length $_[0]; print "INPUT: $_[0]\n"; AsyncArrow::repeat_request; } else { print "DONE\n"; AsyncArrow::done_request; } }))->repeat ->compose(AsyncArrow->arr(sub { $cv->send })) ->run; $p->compose(AsyncArrow->arr(sub { print "total length: $total_length\n" }))->compose(AsyncArrow->arr(\&AsyncArrow::repeat_request)) ->repeat ->run; $cv->recv;
ArrowsはGeneralising Monads to Arrowsにモナドの一般化として載ってます。ざっくり言えば、高階関数の圏の直積を保存するように作った、新たな圏への関手。
で、このJSの実装なんだけど、CpsA の実装までは美しいのに、 AsyncA の実装がイマイチな気がするんですよね。特に ProgressA って、状態をバリバリに持ってるSubject的なクラスなのに、AsyncA を継承して作る利点がイマイチわからず。
ただいま、Ethna
10月 23rd
みなさんお元気ですか。
僕はなんとか生きています。
今日は、久々の Ethna のお話です。
僕が Ethna を触り始めたのは 2004 年末、まだ高校2年生の頃でした。
そして 2007 年ころから rhaco を触り始めたので、それ以来の Ethna です。
つまり、4 年振り 2 回目。
話は変わりまして、この間、 Crocos で開発合宿に行って来ました。
軽井沢に 2 泊 3 日で。軽井沢で所持金 31 円とかたぶん僕だけだったんじゃないかなって思います。
せっかく開発合宿なんで、ちょっと楽しいサービスを妄想しつつ。
Crocos のサービスは基本的にすべて Symfony2 で作られていて、Symfony2 はよくできたフレームワークだなー。とは思ってるんですが、やっぱり開発スピードあがんないよねー。とか、ウェブサービスには向いてないよねー。とかの不満はあるわけです。まあ、お前の頭が悪いからといわれればきっとその通りなんでしょうけどね。
軽井沢まできて Symfony2 も触りたくないし、そうなるともう PHP 界には Ethna しか無いわけですよね。
というわけで、Ethna を使って開発を始めたんですけど、やっぱりテンプレートは Twig 使いたいよねとか、Ethna_UrlHandler とかまじ難しくない?とか、思ってきちゃうんですよね。いやほんと、UrlHandler は謎すぎて未だにわかりません。
ついカッとなった僕は、Ethna_Renderer_Twig と Ethna_UrlHandler_Simple を作りました。
そしてつい先程、Ethna の develop ブランチに Ethna_UrlHandler_Simple が取り込まれましたことをご報告致します。
Twig のほうはちょっとまだフォームヘルパとか半分くらいしか作れてないんで、もう少しかかるかなって感じですが、使ってみたい人は github においてあるので、お試しください。もちろん、残りのフォームヘルパ作ってくれたりしてもいいですよ!ね!!
使い方とか書こうと思ったけどめんどうだからやめます。
簡単に言うと、APPID_UrlHandler で Ethna_UrlHandler_Simple を継承するようにして、action_map の定義をこのへんを参考にして書けば OK です。
おやすみなさい。
YAPCで使うスライドを書いた
10月 22nd
誰得か分かんないけど、一応載せておく。
YAPCで使ったスライドを作る前に用意したサマリー。
(もちろん、スライドを作る途中、作った後にも手を入れてる。)
— ここから —
1. はじめに
マイクテスト(MacBookAirの音をマイクで拾う)
いきさつ
自己紹介
Hokkaido.pmでのお話
2. 音声合成処理
WAVファイル出力
ファイルフォーマット(さらっと)
音階のお話
単音のお話(ワンショット)
3. ドラムマシンを作る
モジュレーション(変調)
キック
スネア / ハイハット
beatsの出力
波形合成(和音)
grooveの実装
ベースと絡める(課題)
強弱をつける(パートを増やす)
音の長さに変化をつける(パートを増やす)
swingさせる(やりましょう)
4. デモンストレーション
Techno
House
swingの説明
Drum’n'Bass
ハイハットパートを2つ(強/弱)
2step
swingきつめ, beatsはタイトに
— ここまで —
これを元にスライドを作って話して来た。
今見ると、9割くらいはこのサマリーに沿って、スライドを作ったらしい。
このサマリーを作った後に手を入れてるとしたら、後半のデモンストレーションだと思う。
デモ用のサンプルはYAPCに行く前夜に完成したのを覚えてる。
どのくらい練習したんだろう。
多分、スライドが出来たのは3連休の最終日だと思うので、
火曜と水曜は練習できたはずだけど、あまり記憶が無い。
というのも、この辺はデモ用のサンプルを作っていたはず。
スライドを書き上げて、適当にしゃべって15分足らずだったのは確認した。
それから、会社の帰りとか、寝る前に1回/日くらい練習したかも。
時間に余裕があることだけは確認したと思う。
トークの内容は、ほぼスライド通り。
どちらかというと、スライド見れば分かるでしょ、を意識してスライドを作った。
本当はもっと日本語を少なくしたかったけど、それは次回の課題に。
あと、どーしても笑いが欲しかったので、最初と最後はあんな感じにした。
いくつかスベッたのは内緒。
台本はあるかというと、もちろん無くて、
特にデモのときは、思い付きでしゃべってたんだけど、あれはよく出来たと思う。
デモの最中に黙り込んじゃうのは避けたいし、笑いが起きてたし。
もし、次回しゃべることがあるとしたら、たぶんHokkaido.pmだと思うけど、
そのときまでに声変わりが来たら、もっと良いトークが出来ると思うので、
一生懸命なんか努力しようと思う。
おしまい。
rubykaigi2011ネットワークの補足とか、LDD11fとかLDD11iとか
10月 22nd
すっかりblogを放置していていまさらなんですがここで予告していたように、るびまで僕の書いたrubykaigi2011のネットワーク話がだいぶ前に公開されていました。
ちょっと抜けがあるので補足しておくと、外部アクセス回線については普通のBフレッツを利用しています。
ただし、大量トラヒックを流すため、家庭用の契約では一発で怒られる可能性があったので、少々高いビジネス用の契約をしています。
臨時Bフレッツみたいな言い回しをしていますが、特に変わった契約はしていません。普通に契約して3日後に解約しただけです。
で、このるびまに書いた記事をベースにして、LDD’11/Fall in KUSHIROで「Rubykaigi2011ネットワークの秘密」というタイトルで話をしてきました。
スライド公開はしません。
なぜかというと、LOCAL DEVELOPER DAY ’11/infraで同じ内容をやるからですww
というわけで、るびまの記事を読んで気になった方は、ぜひ、LDD11iに来てもらえればと思います。
[perl][perl+web][hokkaidopm][planet]「Hokkaido.pm のおかげで結婚できました」
10月 21st
めでたい RT @lestrrat: [YAPC::Asia のおかげで結婚できました」RT @hiratara: 無事に婚姻届が受理されたとこ。
「YAPC::Asia のおかげで結婚できました」エントリありますか RT @hiratara: 無事に婚姻届が受理されたとこ。
エアRTからの無茶ぶりがあったので、YAPC::Asiaの話ではないですがこぼれ話でも。
妻とは付き合いが長かったのに加え、今年は震災もあったことから、「二人の関係を有耶無耶にしたまま人生を終えてしまったら死んでも死にきれない」という思いが少なからずありました。そのタイミングで開催されたのが、Hokkaido.pm #5。ちょうどうまーく実家に帰る口実ができたので、Hokkaido.pmへ行くついでにプロポーズしてそのまま実家に挨拶へ連れて行くという作戦を練りました。妻にも実家にも、「Hokkaido.pm行くからついでに実家に顔出す」、としか言ってなかったので完全にサプライズイベントだったらしく驚かれました(笑)。その後両家の顔合わせなどを経て、昨日無事入籍しました*1。Twitterやfacebook、mixiにてお祝いの言葉を下さった方々、どうもありがとうございました!
昨年Hokkaido.pm が始まったお陰で実家に帰る回数が増え、家族の大切を改めて感じることができるようになりました。そして、#5をタイミングよく開催して頂けたおかげで、重い腰を上げて実家の両親へ挨拶へいくきっかけもできました。Hokkaido.pm がなかったらこんな急に結婚に至ることはなかったと思います。
地方.pm って、ほんとに素晴らしいものですね!
*1:式の段取りこれからなので、落ち着くのはまだまだ先のことになりそうです
Squeak で配列の生成の仕方に #() と {} がある理由
10月 20th
Squeak で配列の生成の仕方に #() と {} がある理由
配列リテラルの #() は要素をリテラルとしてしか解釈しない。そのため、
#(1+3 4+5)
のような式は
#(1 #+ 3 4 #+ 5)
と解釈されてしまう(スペースは無視され、アルファベット・記号はシンボルとして評価される)。
この辺を上手くやる仕組みとして、ピリオドで区切った複数の式の評価結果から Array を生成することができる Squeak の拡張構文 {} が用意された。
{1+3. 4+5} =>#(4 9)
Pharo でデフォルトで有効になっているコードの自動補完の切り方
10月 20th
Pharo でデフォルトで有効になっているコードの自動補完の切り方
今いち思ってるものが候補に出てきてくれずにストレスな自動補完の切り方。
- World メニューから「System > Preferences > Preference Browser」で Preference Browser を表示
- 「Search preferences for」に「ecomp」と入力する
- 絞り込まれた項目中の 「ecompletionEnabled」の enabled のチェックを外す