ディレイっぽいエフェクトを実装してみる

手を抜いてると思われるかも知れませんが、
あながち、間違ってはいないですね!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use v5.14;
use strict;
use warnings;
 
use Cassis;
use constant SAMPLING_RATE => 44100;
 
my $dco = Cassis::DCO::Saw->new( fs => SAMPLING_RATE );
my $filter = Cassis::Iir2::LPF->new( cutoff => 0.3, q => 1.0 );
 
my $eg = Cassis::EG->new(
    fs      => SAMPLING_RATE,
    adsr    => [ 0.03, 0.1, 0.9, 0.3 ],
    curve   => 0.5
);
 
my @wav = ();
{
    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オクターブ上がる)
    );
 
    while ( @pitch_table ) {
        my $pitch = shift @pitch_table;
        $dco->set_pitch( 4.0 + $pitch );
 
        my $eg_out;
        if ( @pitch_table ) {
            $eg->trigger( gatetime => 0.1 );
            $eg_out = $eg->exec( num => SAMPLING_RATE * 0.8 );
        }
        else {
            $eg_out = $eg->one_shot( gatetime => 0.1 );
        }
 
        my $dco_out = $dco->exec( num => scalar(@{$eg_out}) );
 
        my $amp = Cassis::Amp->new();
        my $amp_out = $amp->exec(
            src => $filter->exec( src => $dco_out ),
            mod_volume => {
                src => $eg_out,
                depth => 1.0
            }
        );
 
        push @wav, @{$amp_out};
    }
 
    my @fb_buf = @wav;
    my $fb_gain = 0.2;
    my $delay = 0.25;
 
    my $n = int(SAMPLING_RATE * $delay);
    my @tmp = map { 0.0; } 1..$n;
    while ( 0.1 < $fb_gain ) {
        push @wav, @tmp;
        unshift @fb_buf, @tmp;
 
        my $mixer_out = Cassis::Mixer::mix(
            { src => \@wav, volume => 1.0 },
            { src => \@fb_buf, volume => $fb_gain }
        );
 
        @wav = @{$mixer_out};
        @fb_buf = @{$mixer_out};
        $fb_gain = $fb_gain ** 1.06;
    }
}
 
Cassis::File::write(
    file => 'delay.wav',
    fs => SAMPLING_RATE, channels => [ \@wav ] );

とは言うものの、フィードバック時のゲインの減衰させ方で悩みました。
これで良いのかも、ちょっと分かんないです。。。
エフェクトの調整は、フィードバックさせる回数とかの方がいんですかね。

おしまい。

Leave a Comment