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.3 by root, Tue Dec 28 01:39:43 2004 UTC vs.
Revision 1.7 by root, Thu Mar 3 17:36:58 2005 UTC

1$VERSION = '1.01'; 1$VERSION = '1.011';
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';
13 use PDL; 13 use PDL;
14 use PDL::Audio; 14 use PDL::Audio;
15 15
16=head1 DESCRIPTION 16=head1 DESCRIPTION
17 17
18Oh well ;) Not much "introductury documentation" has been written yet! See 18Oh well ;) Not much "introductory documentation" has been written yet :(
19my other modules for even worse documentation ;)
20 19
21=head2 NOTATION 20=head2 NOTATION
22 21
23Brackets around parameters indicate that the respective parameter is 22Brackets around parameters indicate that the respective parameter is
24optional and will be replaced with some default value when absent (or 23optional and will be replaced with some default value when absent (or
753in C<table>, linearly interpolating between successive points of the 752in C<table>, linearly interpolating between successive points of the
754C<waveform>. 753C<waveform>.
755 754
756=head2 partials2waveshape size*, partials, amplitudes, [phase], [fm_mod/] 755=head2 partials2waveshape size*, partials, amplitudes, [phase], [fm_mod/]
757 756
758Take a list (perl list or pdl) of (integer) C<partials> and a list of 757Take a (perl or pdl) list of (integer) C<partials> and a list of
759C<amplitudes> and generate a single wave shape that results by adding 758C<amplitudes> and generate a single wave shape that results by adding
760these partial sines. 759these partial sines.
761 760
762This could (and should) be used by the C<gen_from_table> generator. 761This could (and should) be used by the C<gen_from_table> generator.
763 762
764=head2 gen_from_partials duration*, frequency/, partials, amplitudes, [phase], [fm_mod/] 763=head2 gen_from_partials duration*, frequency/, partials, amplitudes, [phase], [fm_mod/]
765 764
766Take a list (perl list or pdl) of (possibly noninteger) C<partials> and a 765Take a (perl list or pdl) list of (possibly noninteger) C<partials> and a
767list of C<amplitudes> and generate the waveform resulting by summing up 766list of C<amplitudes> and generate the waveform resulting by summing up
768all these partial sines. 767all these partial sines.
769 768
770=cut 769=cut
771 770
1209Calculates the optimal (in the Chebyshev/minimax sense) FIR filter 1208Calculates the optimal (in the Chebyshev/minimax sense) FIR filter
1210impulse response given a set of band edges, the desired reponse on those 1209impulse response given a set of band edges, the desired reponse on those
1211bands, and the weight given to the error in those bands, using the 1210bands, and the weight given to the error in those bands, using the
1212Parks-McClellan exchange algorithm. 1211Parks-McClellan exchange algorithm.
1213 1212
1214The first argument (the one with the funny name) sets the filter 1213The first argument sets the filter size: C<design_remez_fir> returns as
1215size: C<design_remez_fir> returns as many coefficients as specified via 1214many coefficients as specified by this parameter.
1216this parameter.
1217 1215
1218C<bands> is a vector of band edge pairs (start - end), who specify the 1216C<bands> is a vector of band edge pairs (start - end), which specify the
1219start and end of the bands in the filter specification. These must be 1217start and end of the bands in the filter specification. These must be
1220non-overlapping and sorted in increasing order. Only values between C<0> 1218non-overlapping and sorted in increasing order. Only values between C<0>
1221(0 Hz) and C<0.5> (the Nyquist frequency) are allowed. 1219(0 Hz) and C<0.5> (the Nyquist frequency) are allowed.
1222 1220
1223C<des> specifies the desired gain in these bands. 1221C<des> specifies the desired gain in these bands.
1500 $beta = 2.5 unless defined $beta; 1498 $beta = 2.5 unless defined $beta;
1501 1499
1502 $size = $size->getdim(0) if ref $size; 1500 $size = $size->getdim(0) if ref $size;
1503 $size > 2 or barf "fft window size too small"; 1501 $size > 2 or barf "fft window size too small";
1504 1502
1505 my $midn = $size >> 1; 1503 my $midn = $size >> 1;
1506 my $midm1 = ($size-1) >> 1; 1504 my $midm1 = ($size-1) >> 1;
1507 my $midp1 = ($size+1) >> 1; 1505 my $midp1 = ($size+1) >> 1;
1508 my $dur = zeroes $size; 1506 my $dur = zeroes $size;
1509 my $sf = ($size-1)/$size; 1507 my $sf = ($size-1)/$size;
1510 %fft_window = ( 1508 %fft_window = (
1511 RECTANGULAR => sub { 1509 RECTANGULAR => sub {
1512 $dur->ones 1510 $dur->ones
1513 }, 1511 },
1653 1651
1654=head2 spectrum data, [norm], [window], [beta] 1652=head2 spectrum data, [norm], [window], [beta]
1655 1653
1656Returns the spectrum of a given pdl. If C<norm> is absent (or C<undef>), 1654Returns the spectrum of a given pdl. If C<norm> is absent (or C<undef>),
1657it returns the magnitude of the fft of C<data>. When C<norm> == 1 (or 1655it returns the magnitude of the fft of C<data>. When C<norm> == 1 (or
1658C<eq 'NORM'>, in any case), it returns the magnitude, normalized to be 1656C<eq 'NORM'>, case-insensitive), it returns the magnitude, normalized to be
1659between zero and one. If C<norm> == 0 (or C<eq 'dB'>, in any case), then 1657between zero and one. If C<norm> == 0 (or C<eq 'dB'>, case-insensitive), then
1660it returns the magnitude in dB. 1658it returns the magnitude in dB.
1661 1659
1662C<data> is multiplied with C<window> (if not C<undef>) before calculating 1660C<data> is multiplied with C<window> (if not C<undef>) before calculating
1663the fft, and usually contains a window created with C<gen_fft_window> 1661the fft, and usually contains a window created with C<gen_fft_window>
1664(using C<beta>). If C<window> is a string, it is handed over to 1662(using C<beta>). If C<window> is a string, it is handed over to
1671 1669
1672sub spectrum { 1670sub spectrum {
1673 my ($data, $norm, $window, $beta) = @_; 1671 my ($data, $norm, $window, $beta) = @_;
1674 my $len; 1672 my $len;
1675 if (defined $window) { 1673 if (defined $window) {
1676 $window = gen_fft_window ($data->getdim(0), $window, $beta) unless ref $window; 1674 $window = gen_fft_window ($data->getdim (0), $window, $beta) unless ref $window;
1677 $data = $data * $window; 1675 $data = $data * $window;
1678 $len = $window->getdim(0); 1676 $len = $window->getdim (0);
1679 } else { 1677 } else {
1680 $len = $data->getdim(0); 1678 $len = $data->getdim (0);
1681 } 1679 }
1682 $data = rfft ($data->slice("0:".($len-1))->sever)->slice(",0:".int($len/2))->Cr2p->slice("(0)"); 1680 $data = rfft (
1681 $data->slice ("0:" . ($len - 1))
1682 ->sever
1683 )
1684 ->slice (",0:" . int ($len / 2))
1685 ->PDL::Complex::Cr2p
1686 ->slice ("(0)");
1683 if ($norm == 1 || lc $norm eq "norm") { 1687 if ($norm == 1 || lc $norm eq "norm") {
1684 $data / max $data; 1688 $data / max $data;
1685 } elsif (($norm =~ /^[.0]+$/) || (lc $norm eq "db")) { 1689 } elsif (($norm =~ /^[.0]+$/) || (lc $norm eq "db")) {
1686 log (1e-37 + $data / max $data) * (20 / log 10); 1690 log (1e-37 + $data / max $data) * (20 / log 10);
1687 } else { 1691 } else {
1885 1889
1886pp_addpm {At => Bot}, <<'EOD'; 1890pp_addpm {At => Bot}, <<'EOD';
1887 1891
1888=head1 AUTHOR 1892=head1 AUTHOR
1889 1893
1890Marc Lehmann <pcg@goof.com>. The ideas were mostly taken from common 1894Marc Lehmann <schmorp@schmorp.de>. The ideas were mostly taken from common
1891lisp music (CLM), by Bill Schottstaedt C<bil@ccrma.stanford.edu>. I also 1895lisp music (CLM), by Bill Schottstaedt C<bil@ccrma.stanford.edu>. I also
1892borrowed many explanations (and references) from the clm docs and some 1896borrowed many explanations (and references) from the clm docs and some
1893code from clm.c. Highly inspiring! 1897code from clm.c. Highly inspiring!
1894 1898
1895=head1 SEE ALSO 1899=head1 SEE ALSO

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines