任意のノイズデータを利用する

任意のノイズを簡単に使えるようにするのもCassisを作った理由の一つで、
ノイズにもいろいろ種類があるんだけど、
そのうちの一つであるホワイトノイズを生成してみようと思う。

ちなみに、Cassis::Noiseの出力は-1.0から+1.0の値で、
正確には、-1.0以上+1.0未満が得られる。
っていうのも、こんな感じだから。

our $NOISE_FUNC = sub {
    srand( 2 );
    my @noise = map { rand( 2.0 ) - 1.0; } 1..50000;

    return \@noise;
};

でも、任意のデータを使う方法が2つあって、
一つは、$NOISE_FUNCを書き換える。
もしくは、newするときに引数で渡すことが出来る。

use v5.14;
use strict;
use warnings;

use List::Util qw/shuffle/;
use Cassis;
use constant SAMPLING_RATE => 44100;

my @pitch_table = (
    -9 / 12, # C
    -7 / 12, # D
    -5 / 12, # E
    -4 / 12, # F
    -2 / 12, # G
     0 / 12, # A
     2 / 12, # B
    (-9 / 12) + 1.0, # C(ここから1オクターブ上がる)
    (-7 / 12) + 1.0, # D
    (-5 / 12) + 1.0, # E
    (-4 / 12) + 1.0, # F
    (-2 / 12) + 1.0, # G
    ( 0 / 12) + 1.0, # A
    ( 2 / 12) + 1.0, # B
    (-9 / 12) + 2.0  # C(ここから2オクターブ上がる)
);

my @noise_data = shuffle @pitch_table;
my $noise = Cassis::Noise->new( noise => \@noise_data );
my $dco = Cassis::DCO::Tri->new( fs => SAMPLING_RATE );
my @wav = ();
foreach my $speed ( 0.001, 0.0005, 0.0002, 0.00015, 0.0001 ) {
    my $n = SAMPLING_RATE * 3;

    $noise->set_speed( $speed );
    my $dco_out = $dco->exec(
        num => $n,
        mod_pitch => {
            src => $noise->exec( num => $n ),
            depth => 1.0
        }
    );

    push @wav, @{$dco_out};
}

Cassis::File::write(
    file => 'shuffle_pitch.wav',
    fs => SAMPLING_RATE, channels => [ \@wav ] );

ちょっと裏技っぽいというか、
「ノイズじゃななくね?」って言われるとその通りなんだけど、
こういう使い方も出来る。

ところで、ホワイトノイズだけど、
ホワイトノイズは正規乱数のことらしい。
という訳で、すでに視覚化したものがこちら
そして、コードはこんな感じ。

use v5.14;
use strict;
use warnings;

use Cassis;
use constant SAMPLING_RATE => 44100;

use Math::Random::NormalDistribution;
local $Cassis::Noise::NOISE_FUNC = sub {
    my $gen = rand_nd_generator( 0.0, 0.5 );
    my @noise = map { $gen->() } 1..50000;

    return \@noise;
};

my $noise_out = Cassis::Noise->new()->exec( num => SAMPLING_RATE );
Cassis::File::write(
    file => 'normal_dist_noise.wav',
    fs => SAMPLING_RATE, channels => [ $noise_out ] );

こちらは、$NOISE_FUNCを書き換える例。
ただし、この例だと生成される乱数の範囲は-1.0から+1.0ではなくて、
-1.0と+1.0を超えた分はCassis::File::writeでクリップされる。

さて、次回からはフィルタですかね!

おしまい。

Leave a Comment