Hokkaido.pm Casual#19に行ってきました

今回は久々に10人も参加して頂きました。
みなさん、お疲れさまでした。
次回は、第3水曜日の12/18を予定していますので、
よろしくお願いします。

さっそく内容の方なんですが、
印象に残ってるのは、今回初参加の学生さんですね。
久々のご新規さんということで、ちょっとテンションが上がりました。

あと、メモに残ってるコードはこちら。
$ echo "a b c" | perl -anE 'say $F[2]'
c
$ echo " a b c" | perl -anE 'say $F[2]'
c

先頭にスペースが入ってても、3つ目の”c”が得られる訳ですが、
これはawkのデフォルトの振る舞いをエミュレートしているそうです。(*1)

あと、自分のLTで使ったコードはこちら。

use strict;
use warnings;
use v5.10;

use Net::OpenSoundControl::Client;
use Data::Dumper;

# アルファベットと+/-で表現した音程から周波数に変換する
sub note_to_freq {
    my $note = shift;

    # オクターブ = +3, ラの音の周波数
    my $FREQ_OF_A3 = 440.0;

    my %NOTE_TO_OFFSET = (
        C => -9,
        D => -7,
        E => -5,
        F => -4,
        G => -2,
        A =>  0,
        B =>  2
    );

    # MIDIだとオクターブは-2から+8まであるが、
    # 0から+8までサポートする
    my $freq = 0;
    if ( $note =~ /^[A-G][+|-]?[0-8]?/ ) {
        my @tmp = split //, $note;
        my $idx = $NOTE_TO_OFFSET{ shift @tmp };

        # A3の場合、$idx=0で440Hzが算出される
        foreach my $ch (@tmp) {
            if ( $ch eq '+' ) {
                $idx++;
            }
            elsif ( $ch eq '-' ) {
                $idx--;
            }
            else { 
                $idx += ( (int($ch) - 3) * 12 );
            }
        }

        $freq = $FREQ_OF_A3 * ( 2 ** ($idx / 12.0) );
    }
    else {
        warn '"' . $note . '" is not note.';
    }

    return $freq;
}

my $client = Net::OpenSoundControl::Client->new(
    Host => "localhost",
    Port => 57120 ) or die "Could not start client: $@\n";

my $app = sub {
    my $env = shift;

    if ( $env->{REQUEST_URI} eq '/favicon.ico' ) {
        open my $fh, '<:raw', './favicon.png';
        return [
            200, [ "Content-Type" => "image/png" ], $fh
        ];
    }
    else {
        my $req = substr $env->{REQUEST_URI}, 1;
        if ( $req =~ /^[A-G][+|-]?[0-8]?/ ) {
            my $freq = note_to_freq( $req );
            $client->send( ['/1/osc', 'i', 1, 'f', $freq, 'f', 500] );
            return [
                200,
                [ 'Content-Type' => 'text/plain' ],
                [ 'freq = ', $freq ]
            ];
        }
        else {
            return [
                200,
                [ 'Content-Type' => 'text/plain' ],
                [ Dumper($env) ]
            ];
        }
    }
};

これを使って音を鳴らすのに必要なpdファイルは、こちらにある”demo2.pd”です。
https://github.com/techno-cat/LT-20130309_pm

こちらも参考にどうぞ。
第15回 Perl meets beats―鳴らして学ぶシンセサイザー入門(1)gihyo.jp

おしまい。

(*1) http://perldoc.jp/func/split

Leave a Comment