PDLを使ってみよう

自己紹介

PDLを使ってみよう

PDLって?

使ってみよう(1)

使ってみよう(2)

こういうのが簡単!

use v5.10;
use PDL;

my $a = pdl( 2, 4 );
say '$a     => ', $a;     # $a     => [2 4]
say '$a + 2 => ', $a + 2; # $a + 2 => [4 6]
say '$a - 2 => ', $a - 2; # $a - 2 => [0 2]
say '$a * 2 => ', $a * 2; # $a * 2 => [4 8]
say '$a / 2 => ', $a / 2; # $a / 2 => [1 2]

使ってみよう(3)

行列の宣言

use v5.10;
use PDL;
use PDL::Matrix;

my $a = mpdl( [0, 1, 2], [2, 1, 0], [0, 0, 2] );
say ref $a; # PDL::Matrix
say $a;
#[
# [0 1 2]
# [2 1 0]
# [0 0 2]
#]

使ってみよう(4)

逆行列の計算

use v5.10;
use PDL;
use PDL::Matrix;

my $a = mpdl( [0, 1, 2], [2, 1, 0], [0, 0, 2] );
my $b = inv $a;
say $b;
#[
# [-0.5    1    0]
# [ 0.5    0    0]
# [ 0.5   -1  0.5]
#]

使ってみよう(5)

逆行の積

use v5.10;
use PDL;
use PDL::Matrix;

my $a = pdl( [0, 1, 2], [2, 1, 0], [0, 0, 2] );
my $b = inv $a;
my $c = $a x $b; # 'x'を使ってる点に注意
say $c;
#[
# [1 0 0]
# [0 1 0]
# [0 0 1]
#] 

まとめ

帰ってきたPerl meets beats

Perl meets beatsって?

用意するもの

PDLで書き換えてみる

ミックス処理

クリップ処理

PDLで書き換えてみる

各チャンネルの波形を生成

PDLで書き換えてみる

すべての要素に対する掛け算(音量の適用)

PDLで書き換えてみる

配列同士の足し算

PDLで書き換えてみる

ミックス処理(Before)

my @samples = ();
foreach my $ch_info ( @beats ) {
    my $ch = create_channel( $bpm, $ch_info );
    my $vol = $ch_info->{vol};
    for (my $i=0; $i<scalar(@{$ch}); $i++) {
        $samples[$i] += ( $ch->[$i] * $vol );
    }
}

PDLで書き換えてみる

ミックス処理(After)

my $samples = zeros( 0 );
foreach my $ch_info ( @beats ) {
    my $ch = pdl(
        create_channel($bpm, $ch_info)
    ) * $ch_info->{vol};

    # ミックスするデータの長さを揃える
    ...

    $samples += $ch;
}

PDLで書き換えてみる

ミックス処理(After)

my $samples = zeros( 0 );
foreach my $ch_info ( @beats ) {
    my $ch = pdl(
        create_channel($bpm, $ch_info)
    ) * $ch_info->{vol};

    # ミックスするデータの長さを揃える
    if ( $samples->nelem < $ch->nelem ) {
        $samples = $samples->append( zeros($ch->nelem - $samples->nelem) );
    }
    elsif ( $ch->nelem < $samples->nelem ) {
        $ch = $ch->append( zeros($samples->nelem - $ch->nelem) );
    }

    $samples += $ch;
}

PDLで書き換えてみる

クリップ処理(Before)

@samples = map {
    ( 1.0 < $_ )
        ? 1.0
        : ( ($_ < -1.0) ? -1.0 : $_ );
} @samples;

PDLで書き換えてみる

クリップ処理(After)

$samples = $samples->clip( -1, 1 );

まとめ

ご静聴、ありがとうございました

/

#