ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PDL-Audio/audio.pd
(Generate patch)

Comparing PDL-Audio/audio.pd (file contents):
Revision 1.6 by root, Tue Dec 28 02:14:49 2004 UTC vs.
Revision 1.9 by root, Tue Nov 8 18:56:06 2005 UTC

1$VERSION = '1.01'; 1$VERSION = '1.1';
2 2
3pp_setversion $VERSION; 3pp_setversion $VERSION;
4pp_beginwrap (); # force error with older PPs 4pp_beginwrap (); # force error with older PPs
5 5
6pp_addpm {At => Top}, <<'EOD'; 6pp_addpm {At => Top}, <<'EOD';
275 275
276=cut 276=cut
277 277
278sub describe_audio($) { 278sub describe_audio($) {
279 my $pdl = shift; 279 my $pdl = shift;
280 my ($samples, $channels) = $pdl->dims; 280 my ($channels, $samples) = $pdl->dims;
281 my $chan = $channels < 2 ? "mono" : 281 my $chan = $channels < 2 ? "mono" :
282 $channels == 2 ? "stereo" : 282 $channels == 2 ? "stereo" :
283 $channels == 4 ? "quad channel" : 283 $channels == 4 ? "quad channel" :
284 "$channel channel"; 284 "$channels channel";
285 my $desc = "$chan sound with $samples samples"; 285 my $desc = "$chan sound with $samples samples";
286 $desc .= sprintf ", original name \"%s\"", $pdl->path if $pdl->path; 286 $desc .= sprintf ", original name \"%s\"", $pdl->path if $pdl->path;
287 $desc .= sprintf ", type %d (%s)", $pdl->filetype, sound_type_name($pdl->filetype) if $pdl->filetype; 287 $desc .= sprintf ", type %d (%s)", $pdl->filetype, sound_type_name($pdl->filetype) if $pdl->filetype;
288 $desc .= sprintf ", rate %d/s (duration %.2fs)", $pdl->rate, $samples/$pdl->rate if $pdl->rate; 288 $desc .= sprintf ", rate %d/s (duration %.2fs)", $pdl->rate, $samples/$pdl->rate if $pdl->rate;
289 $desc .= sprintf ", format %d (%s)", $pdl->format, sound_format_name($pdl->format) if $pdl->format; 289 $desc .= sprintf ", format %d (%s)", $pdl->format, sound_format_name($pdl->format) if $pdl->format;
290 $desc; 290 $desc
291} 291}
292 292
293=head2 raudio path, [option-hash], option => value, ... 293=head2 raudio path, [option-hash], option => value, ...
294 294
295Reads audio data into the piddle. Options can be anything, most useful values are 295Reads audio data into the piddle. Options can be anything, most useful
296C<filetype>, C<rate>, C<channels> and C<format>. 296values are C<filetype>, C<rate>, C<channels> and C<format>. The returned
297piddle is represents "time" in the outer dimension, and samples in the
298inner (i.e. scalars for mono files, 2-vectors for stereo files):
299
300 [ [left0, right0], [left1, right1], [left2, right2], ...]
297 301
298 # read any file 302 # read any file
299 $pdl = raudio "file.wav"; 303 $pdl = raudio "file.wav";
300 # read a file. if it is a raw file preset values 304 # read a file. if it is a raw file preset values
301 $pdl = raudio "file.raw", filetype => FILE_RAW, rate => 44100, channels => 2; 305 $pdl = raudio "file.raw", filetype => FILE_RAW, rate => 44100, channels => 2;
302 306
303=head2 waudio pdl, [option-hash], option => value, ... 307=head2 waudio pdl, [option-hash], option => value, ...
304 308
305Writes a pdl as a file. The path is taken from the header (or the options), e.g.: 309Writes a pdl as a file. See L<raudio> for options and format. The path and
310other metadata is taken from the header, whcih cna be overwritten using
311options, e.g.:
306 312
307 # write a file, using the header of another piddle 313 # write a file, using the header of another piddle
308 $pdl->waudio($orig_file->gethdr); 314 $pdl->waudio ($orig_file->gethdr);
309 # write pdl as au file, take rate from the header 315 # write pdl as .au file, take rate from the header
310 $pdl->waudio(path => "piddle.au", filetype => FILE_AU, format => FORMAT_16_LINEAR; 316 $pdl->waudio (path => "piddle.au", filetype => FILE_AU, format => FORMAT_16_LINEAR;
311 317
312=cut 318=cut
313 319
314# read a sound file 320# read a sound file
315sub raudio { 321sub raudio {
338 (close_sound_input $fd) >= 0 or barf "$path: ".audio_error_name audio_error; 344 (close_sound_input $fd) >= 0 or barf "$path: ".audio_error_name audio_error;
339 $pdl = $pdl->short->xchg(0,1); 345 $pdl = $pdl->short->xchg(0,1);
340 $pdl = $pdl->clump(2) if $channels == 1; 346 $pdl = $pdl->clump(2) if $channels == 1;
341 $pdl->sever; 347 $pdl->sever;
342 $pdl->sethdr(\%hdr); 348 $pdl->sethdr(\%hdr);
343 $pdl; 349 $pdl
344} 350}
345 351
346sub _audio_make_plain { 352sub _audio_make_plain {
347 my $pdl = shift; 353 my $pdl = shift;
348 if ($pdl->getndims == 1) { 354 if ($pdl->getndims == 1) {
349 ($pdl, 1, $pdl->getdim(0)); 355 ($pdl, 1, $pdl->getdim(0))
350 } else { 356 } else {
351 ($pdl->xchg(0,1)->clump(-1), ($pdl->dims)[1,0]); 357 ($pdl->xchg(0,1)->clump(-1), $pdl->dims)
352 } 358 }
353} 359}
354 360
355sub waudio { 361sub waudio {
356 my $pdl = shift; 362 my $pdl = shift;
361 $hdr{format} ||= FORMAT_16_LINEAR; 367 $hdr{format} ||= FORMAT_16_LINEAR;
362 $hdr{rate} ||= 44100; 368 $hdr{rate} ||= 44100;
363 369
364 ($pdl, $channels, $frames) = _audio_make_plain $pdl->convert(long); 370 ($pdl, $channels, $frames) = _audio_make_plain $pdl->convert(long);
365 371
372 1 <= $channels && $channels <= 2
373 or croak "can only write mono or stereo (one or two channel) files, not $channels channel files";
374
366 my $fd = open_sound_output $hdr{path}, $hdr{rate}, $channels, $hdr{format}, $hdr{filetype}, $hdr{comment}; 375 my $fd = open_sound_output $hdr{path}, $hdr{rate}, $channels, $hdr{format}, $hdr{filetype}, $hdr{comment};
367 $fd >= 0 or barf "$hdr{$path}: ".audio_error_name audio_error; 376 $fd >= 0 or barf "$hdr{$path}: ".audio_error_name audio_error;
368 $pdl->clump(-1)->write_sound($fd, $channels, $frames) 377 $pdl->clump(-1)->write_sound($fd, $channels, $frames)
369 >= 0 or barf "$path: ".audio_error_name audio_error; 378 >= 0 or barf "$path: ".audio_error_name audio_error;
370 (close_sound_output $fd, mus_samples2bytes $hdr{format}, $frames) 379 (close_sound_output $fd, mus_samples2bytes $hdr{format}, $frames * $channels)
371 >= 0 or barf "$hdr{$path}: ".audio_error_name audio_error; 380 >= 0 or barf "$hdr{$path}: ".audio_error_name audio_error;
372} 381}
373 382
374=head2 cut_leading_silence pdl, level 383=head2 cut_leading_silence pdl, level
375 384
390sub cut_leading_silence { 399sub cut_leading_silence {
391 my $pdl = shift; 400 my $pdl = shift;
392 my $level = 1*shift; 401 my $level = 1*shift;
393 my $skip = which (abs($pdl) > $level); 402 my $skip = which (abs($pdl) > $level);
394 $skip = $skip->nelem ? $skip->at(0) : 0; 403 $skip = $skip->nelem ? $skip->at(0) : 0;
395 $pdl->slice("$skip:-1"); 404 $pdl->slice("$skip:-1")
396} 405}
397 406
398sub cut_trailing_silence { 407sub cut_trailing_silence {
399 my $pdl = shift; 408 my $pdl = shift;
400 my $level = 1*shift; 409 my $level = 1*shift;
401 $level = 400000; 410 $level = 400000;
402 my $skip = which (abs($pdl) > $level); 411 my $skip = which (abs($pdl) > $level);
403 $skip = $skip->nelem ? $skip->at(-1) : -1; 412 $skip = $skip->nelem ? $skip->at(-1) : -1;
404 $skip-- if $skip > 0; 413 $skip-- if $skip > 0;
405 $pdl->slice("0:$skip"); 414 $pdl->slice("0:$skip")
406} 415}
407 416
408sub cut_silence { 417sub cut_silence {
409 $_[0]->cut_leading_silence($_[1]) 418 $_[0]->cut_leading_silence($_[1])
410 ->cut_trailing_silence($_[1]); 419 ->cut_trailing_silence($_[1])
411} 420}
412 421
413# have we been a bad boy? 422# have we been a bad boy?
414 423
415for (@METHODS) { 424for (@METHODS) {
1889 1898
1890pp_addpm {At => Bot}, <<'EOD'; 1899pp_addpm {At => Bot}, <<'EOD';
1891 1900
1892=head1 AUTHOR 1901=head1 AUTHOR
1893 1902
1894Marc Lehmann <pcg@goof.com>. The ideas were mostly taken from common 1903Marc Lehmann <schmorp@schmorp.de>. The ideas were mostly taken from common
1895lisp music (CLM), by Bill Schottstaedt C<bil@ccrma.stanford.edu>. I also 1904lisp music (CLM), by Bill Schottstaedt C<bil@ccrma.stanford.edu>. I also
1896borrowed many explanations (and references) from the clm docs and some 1905borrowed many explanations (and references) from the clm docs and some
1897code from clm.c. Highly inspiring! 1906code from clm.c. Highly inspiring!
1898 1907
1899=head1 SEE ALSO 1908=head1 SEE ALSO

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines