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