ディレイっぽいエフェクトを実装してみる
手を抜いてると思われるかも知れませんが、
あながち、間違ってはいないですね!
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