1 |
#!/usr/bin/perl |
2 |
|
3 |
#use blib; |
4 |
use PDL; |
5 |
use PDL::Audio; |
6 |
#use PDL::Graphics::PGPLOT; |
7 |
use PDL::Audio::Pitches; |
8 |
use PDL::Dbg; |
9 |
use PDL::Complex; |
10 |
|
11 |
$|=1; |
12 |
|
13 |
*_dur2time = *PDL::Audio::_dur2time; |
14 |
sub HZ (){ 22050 }; |
15 |
|
16 |
sub freqz { |
17 |
my ($a, $b, $w) = @_; |
18 |
$w = 512 unless defined $w; |
19 |
$w = zeroes($w)->xlinvals(0,M_PI*($w-1)/$w) unless ref $w; |
20 |
$w = exp i * r2C $w; |
21 |
|
22 |
Cabs(Cdiv($a->rCpolynomial($w),$b->rCpolynomial($w))); |
23 |
} |
24 |
|
25 |
sub play { |
26 |
my $pdl = shift; |
27 |
#line $pdl; |
28 |
$pdl->scale2short->playaudio(rate => HZ, @_); |
29 |
} |
30 |
|
31 |
$pdl = raudio "kongas.wav"; |
32 |
|
33 |
print describe_audio($pdl), "\n"; |
34 |
|
35 |
$pdl = $pdl->float->filter_src($pdl->rate / HZ); |
36 |
$pdl = $pdl->filter_center; |
37 |
|
38 |
my @stdenv = (pdl(0,0.1,0.2,0.9,1), pdl(0,1,0.6,0.6,0)); |
39 |
$env = gen_env $pdl, @stdenv; |
40 |
|
41 |
sub tst($$) { |
42 |
push @tests, [$_[0], $_[1]]; |
43 |
} |
44 |
|
45 |
tst src, sub { |
46 |
for (qw(22050 11025 8000)) { |
47 |
print " $_"; play $pdl->filter_src(44100 / $_), rate => $_; |
48 |
} |
49 |
}; |
50 |
|
51 |
tst contrast_enhance, sub { |
52 |
for (qw(0.1 0.2 0.3 0.6 1)) { |
53 |
print " $_"; play $pdl->filter_contrast_enhance($_); |
54 |
} |
55 |
}; |
56 |
|
57 |
tst granulate, sub { |
58 |
for (qw(1.5 1.3 1.1 1.0 0.8 0.6 0.5)) { |
59 |
print " $_"; play $pdl->filter_granulate($_); |
60 |
} |
61 |
print " +SRC:"; |
62 |
for (qw(1.5 1.3 1.1 1.0 0.8 0.6 0.5)) { |
63 |
print " $_"; play $pdl->filter_granulate($_)->filter_src($_), rate => 44100; |
64 |
} |
65 |
}; |
66 |
|
67 |
tst modulated_src, sub { |
68 |
print " 2 hz 0.7 sine..."; |
69 |
play $pdl->filter_src(1, 5, 0.7 * gen_oscil $pdl, 2/HZ); |
70 |
print " 5 hz 0.3 sine..."; |
71 |
play $pdl->filter_src(1, 5, 0.3 * gen_oscil $pdl, 20/HZ); |
72 |
print " 90 hz 0.5 sine..."; |
73 |
play $pdl->filter_src(1, 5, 0.5 * gen_oscil $pdl, 90/HZ); |
74 |
print " 300 hz 0.8 sine..."; |
75 |
play $pdl->filter_src(1, 5, 0.8 * gen_oscil $pdl, 300/HZ); |
76 |
}; |
77 |
|
78 |
tst 'ring_modulate', sub { |
79 |
print " ring modulated with 20 hz sine"; |
80 |
play $pdl->ring_modulate(gen_oscil $pdl, 20 / HZ); |
81 |
print " ring modulated with 1000 hz sine"; |
82 |
play $pdl->ring_modulate(gen_oscil $pdl, 1000 / HZ); |
83 |
}; |
84 |
|
85 |
tst 'touchtones', sub { |
86 |
my @h = ( 697, 697, 697, 770, 770, 770, 852, 852, 852, 941, 941, 941); |
87 |
my @v = (1209,1336,1477,1209,1336,1477,1209,1336,1477,1209,1336,1477); |
88 |
my $dur = HZ*0.22; |
89 |
my $env = gen_env $dur, pdl(0,1,2,9,10), pdl(0,1,0.9,0.9,0); |
90 |
my @mix; |
91 |
for (0..$#h) { |
92 |
my ($h, $v) = ($h[$_], $v[$_]); |
93 |
$h = $env * gen_oscil $dur, $h/HZ; |
94 |
$v = $env * gen_oscil $dur, $v/HZ; |
95 |
push @mix, ($_*$dur, $h, $_*$dur, $v); |
96 |
}; |
97 |
play audiomix @mix; |
98 |
}; |
99 |
|
100 |
tst noise_fm, sub { |
101 |
my $pdl; |
102 |
print " 100 hz"; |
103 |
$pdl = gen_rand 2*HZ, 100/HZ; |
104 |
$pdl = gen_oscil $pdl, 880/HZ, 0, $pdl * $pdl->xlinvals(0.001,0.1); |
105 |
play $pdl * gen_env $pdl, @stdenv; |
106 |
print " 6000 hz"; |
107 |
$pdl = gen_rand 2*HZ, 6000/HZ; |
108 |
$pdl = gen_oscil $pdl, 880/HZ, 0, $pdl * $pdl->xlinvals(0.001,0.1); |
109 |
play $pdl * gen_env $pdl, @stdenv; |
110 |
}; |
111 |
|
112 |
tst simple_fm, sub { |
113 |
my $fm = gen_triangle $pdl, 16/HZ; |
114 |
$fm *= $fm->xlinvals(0,0.1); |
115 |
print " 900 hz sine + vibrato"; play $env * gen_oscil $pdl, 900/HZ, 0, $fm; |
116 |
print " 900 hz sine + sound"; play $env * gen_oscil $pdl, 1/HZ, 0, $pdl * 0.08; |
117 |
}; |
118 |
|
119 |
tst filters, sub { |
120 |
print " filter_lir(<0.05s echo>)"; play $pdl->filter_lir(pdl(0),pdl(0.5), pdl(HZ*0.05), pdl(0.5)); |
121 |
print " ppolar(0.8,220)"; play $pdl->filter_ppolar(0.8,220); |
122 |
print " zpolar(0.8,220)"; play $pdl->filter_zpolar(0.8,220); |
123 |
}; |
124 |
|
125 |
tst 'waveshaping', sub { |
126 |
# this is the spectrum of a cello playing as3 |
127 |
my @i = (1.01, 1.99, 2.99, 4.00, 5.00, 6.00, 6.99, 8.00, 9.00, 9.98, |
128 |
10.99, 11.99, 13.00, 14.01, 14.99, 16.02, 17.00, 17.98, 19.00, 20.01, |
129 |
21.02, 22.02, 22.22, 22.93, 24.05, 25.04, 25.99, 27.00, 29.03); |
130 |
|
131 |
my @a = (.0839, .0414, .1265, .0196, .0377, .0117, .0111, .0151, .0207, |
132 |
.0033, .0090, .0039, .0039, .0031, .0038, .0023, .0026, .0069, .0020, |
133 |
.0017, .0007, .0006, .0002, .0001, .0003, .0002, .0003, .0003, .0003); |
134 |
|
135 |
# add a slight vibrato |
136 |
my $tri = gen_triangle 4*HZ, 1.5/HZ; |
137 |
my $pdl = gen_from_partials (4*HZ, as3/HZ, \@i, \@a, 0, 16/HZ*$tri); |
138 |
|
139 |
play $pdl * gen_env $pdl, @stdenv; |
140 |
}; |
141 |
|
142 |
0&&tst simple_generators, sub { |
143 |
print " 1/f noise"; play $env * gen_rand_1f $pdl; |
144 |
print " 900 hz sine"; play $env * gen_oscil $pdl, 900/HZ; |
145 |
print " 900 hz triangle"; play $env * gen_triangle $pdl, 900/HZ; |
146 |
print " 900 hz asyfm"; play $env * gen_asymmetric_fm $pdl, 900/HZ; |
147 |
print " 900 hz sine summation"; play $env * gen_sine_summation $pdl, 900/HZ, 0, 5; |
148 |
print " 900 hz sum of cosines"; play $env * gen_sum_of_cosines $pdl, 900/HZ, 0, 5; |
149 |
}; |
150 |
|
151 |
tst noise_filtering, sub { |
152 |
my $pdl = gen_rand 2*HZ, 1; |
153 |
$pdl = $pdl->filter_ppolar(0.97, 440/HZ); |
154 |
$pdl = $pdl->filter_lir(pdl(0),pdl(0.1), pdl(HZ/440),pdl(0.99)); |
155 |
play $pdl * gen_env $pdl, @stdenv; |
156 |
}; |
157 |
|
158 |
tst 'spectrum', sub { |
159 |
$pdl = gen_fft_window(100, KAISER, -1.0); |
160 |
#line spectrum $pdl, 'db'; |
161 |
#line spectrum $pdl, db', KAISER; |
162 |
#line spectrum $pdl, 'db'; |
163 |
exit; |
164 |
} if 0; |
165 |
|
166 |
tst 'karplus', sub { |
167 |
my $pdl = concat gen_rand(0.4*HZ, 1), zeroes(5.0*HZ); |
168 |
|
169 |
my $dur = 2*HZ; |
170 |
my $freq = 440/HZ; |
171 |
my $damping = -0.5/HZ; |
172 |
|
173 |
$freq *= M_2PI; |
174 |
|
175 |
my $e = exp $damping; |
176 |
my $c1 = 2 * $e * cos $freq; |
177 |
my $c2 = $e * $e; |
178 |
my $tm = atan2 ($freq, $damping) / $freq; |
179 |
my $scale = sqrt ($damping*$damping + $freq*$freq) * exp (-$damping*$tm) * HZ / 750000; |
180 |
print "$scale, $c1, $c2\n"; |
181 |
$pdl = $pdl->filter_lir(pdl(1), pdl($scale), |
182 |
pdl(1, 2, int(1/$freq+6)), pdl(-$c1, $c2, -$scale*0.1)); |
183 |
line $pdl; |
184 |
play $pdl * gen_env $pdl, @stdenv; |
185 |
|
186 |
} if 0; |
187 |
|
188 |
tst 'karplus2', sub { |
189 |
my $pdl = concat gen_rand(1.*HZ, 1), zeroes(5.0*HZ); |
190 |
|
191 |
my $dur = 2*HZ; |
192 |
my $freq = 440/HZ; |
193 |
my $freq2 = 88/HZ; |
194 |
my $reson = 0.05; |
195 |
|
196 |
$pdl = $pdl->filter_lir( |
197 |
pdl(1, 2, 1,2), |
198 |
pdl(-$reson*$reson, 2*$reson*cos(M_2PI*$freq), |
199 |
-$reson*$reson, 2*$reson*cos(M_2PI*$freq2)), |
200 |
pdl(int(1/$freq),int(1/$freq2)), pdl(0.49, 0.499)); |
201 |
line $pdl; |
202 |
play $pdl; # * gen_env $pdl, @stdenv; |
203 |
} if 0; |
204 |
|
205 |
tst 'vibro', sub { |
206 |
my $pdl; |
207 |
$pdl = gen_oscil 2*HZ, 40/HZ; |
208 |
#$pdl = gen_oscil 2*HZ, 40/HZ, 0, $pdl->xlinvals(0,80/HZ); |
209 |
#$pdl = $pdl->filter_zpolar(0.9, 80/HZ); |
210 |
#line $pdl->slice("0:30000"); |
211 |
$pdl = pdl(1,1)->partials2polynomial(1)->polynomial($pdl); |
212 |
line $pdl; |
213 |
play $pdl; |
214 |
exit; |
215 |
} if 0; |
216 |
|
217 |
tst chorus, sub { |
218 |
play $pdl; |
219 |
my $lfo = $osc = 0.02 * gen_rand $pdl, 30/HZ; |
220 |
my $dly = $pdl->filter_src(1, undef, $lfo); |
221 |
play $dly->rshift(0.030*HZ) + $pdl; |
222 |
}; |
223 |
|
224 |
tst phazor, sub { |
225 |
play $pdl; |
226 |
print "rfft..."; |
227 |
my $fft = rfft($pdl)->Cr2p; |
228 |
my $im = im $fft; $im .= $im->rshift(-10000); |
229 |
print "irfft..."; |
230 |
my $fft = irfft($fft->Cp2r); |
231 |
play $fft; |
232 |
} if 0; |
233 |
|
234 |
tst strong, sub { |
235 |
# as done originally by Alex Strong |
236 |
my $pdl = zeroes HZ*5; |
237 |
my $freq = int (HZ/220); |
238 |
my $x = $pdl->slice("0:".($freq-1)); $x .= gen_rand $x, 1; |
239 |
|
240 |
$pdl = $pdl->filter_lir(pdl(0),pdl(1),pdl($freq,$freq+1),pdl(0.5,0.5)); |
241 |
play $pdl; |
242 |
}; |
243 |
|
244 |
#print "original version..."; play $pdl; print "\n"; |
245 |
|
246 |
for (reverse @tests) { |
247 |
my ($name, $sub) = @$_; |
248 |
print "$name..."; |
249 |
&$sub; |
250 |
print "\n"; |
251 |
} |
252 |
|
253 |
exit; |
254 |
|
255 |
#$pdl2 = filter_granulate $pdl, 0.8, rate => 44100; |
256 |
$pdl2 = filter_contrast_enhance $pdl, 0.1; |
257 |
#$pdl->scale2short->playaudio(rate => 44100); |
258 |
$pdl2->scale2short->playaudio(rate => 44100); |
259 |
exit; |
260 |
|
261 |
$pdl = zeroes(4096); |
262 |
$pdl = sin $pdl->xlinvals(0,20) + sin $pdl->xlinvals(0,50); |
263 |
$pz = zeroes(40960); |
264 |
$pdl2 = filter_src ($pdl, 0.5, 80, $pz); |
265 |
#line $pdl2; |
266 |
$pdl2->scale2short->playaudio; |
267 |
|
268 |
|
269 |
|
270 |
|