File Coverage

blib/lib/Music/Note/Frequency.pm
Criterion Covered Total %
statement 34 37 91.8
branch 6 10 60.0
condition 7 20 35.0
subroutine 7 7 100.0
pod 3 3 100.0
total 57 77 74.0


line stmt bran cond sub pod time code
1             package Music::Note::Frequency;
2              
3 3     3   37216 use 5.006;
  3         7  
4 3     3   10 use strict;
  3         4  
  3         48  
5 3     3   9 use warnings;
  3         12  
  3         121  
6              
7             our @ISA=("Music::Note");
8 3     3   1181 use Music::Note;
  3         3346  
  3         1055  
9              
10             sub new {
11 2     2 1 116 my ($class,@args)=@_;
12              
13 2         5 our $self={};
14 2         3 our $base=440;
15            
16 2 100       12 if (ref($args[0]) =~/HASH/) {
    50          
17 1 50 33     5 if (defined($args[0]->{base}) && $args[0]->{base} =~ /^\d+$/) {
18 0         0 $base=$args[0]->{base};
19 0         0 delete $args[0]->{base};
20             }
21            
22 1         4 $self=Music::Note->new($args[0]);
23             } elsif (scalar(@args) > 0) {
24             #my $type='ISO';
25             #my $step='C'; my $alter=0;my $octave=4;
26 1         2 $base=pop @args;
27 1 50 33     11 if ($base !~ /^\d*\.?\d*$/ || $base !~ /\d/ || $base < 0) {
      33        
28 1         2 push @args, $base;
29 1         1 $base=440;
30             };
31 1         5 $self=Music::Note->new(@args);
32             } else {
33 0         0 $self=Music::Note->new();
34             }
35              
36 2         61 $self->{base}=$base;
37              
38 2         3 bless $self,$class;
39 2         5 return $self;
40             }
41            
42              
43             =head1 NAME
44              
45             Music::Note::Frequency - returns the note's frequency in Hertz (Hz).
46              
47             =head1 VERSION
48              
49             Version 0.05
50              
51             =cut
52              
53             our $VERSION = '0.05';
54              
55              
56             =head1 SYNOPSIS
57              
58             use Music::Note::Frequency;
59              
60             # create a new note object at C4 with base frequency A4=440 Hz.
61             my $note = Music::Note::Frequency->new();
62              
63             # all of these create a new object with note = C4 and base
64             # frequency A4=431 Hz (default is 440):
65             my $note = Music::Note::Frequency->new(431);
66             my $note = Music::Note::Frequency->new("C4",431);
67             my $note = Music::Note::Frequency->new("C4","ISO",431);
68             my $note = Music::Note::Frequency->new({ step=>'C',
69             alter=>0,
70             octave=>4,
71             base=>431});
72             my $note = Music::Note::Frequency->new({base=>431});
73            
74              
75             # get the frequency of a note
76             my $note = Music::Note::Frequency->new("C4");
77             print $note->frequency(); # prints 261.625565300599
78             # change the note's base frequency
79             my $base=$note->base(431); # sets new base to 431 Hz
80             print $note->frequency(); # prints 256.274133283086
81              
82              
83             =head1 DESCRIPTION
84              
85             This module extends Music::Note to provide a method to return the frequency in Hertz (Hz) of the object's note from an equal-tempered tuning. The formula for calculating frequency values was taken from L and modified to support MIDI pitch values instead of piano key numbers and alternative base frequencies:
86              
87             f(n) = 2**((n - 69)/12) * base
88              
89            
90              
91             =head1 METHODS
92              
93             =head2 new()
94              
95             =head2 new(NOTE)
96              
97             =head2 new(NOTE,TYPE)
98              
99             =head2 new(NOTE,TYPE,BASE)
100              
101             =head2 new(NOTE,BASE)
102              
103             =head2 new(BASE)
104              
105             =head2 new(\%args)
106              
107             Creates and returns a Music::Note::Frequency object with the values specified in the arguments or defaults of note value = C4 and frequency base (value of A4) = 440 Hz. Otherwise takes the same arguments as described in the perldoc for Music::Note, with the addition of BASE as an optional (last) numeric argument or as a key/value pair in the passed argument hashref. Example:
108              
109             my $note = Music::Note::Frequency->new({step=>'C',octave=>4,base=>415});
110              
111             =head2 frequency()
112              
113             Returns the frequency in Hertz (Hz) of the note from an equal-tempered tuning. Calculates the frequency from the above formula. Supports all note types that are supported by Music::Note.
114              
115              
116             =cut
117              
118             sub frequency {
119 6     6 1 15 my $self = shift;
120 6         14 my $n=$self->to_midinum();
121            
122 6         41 my $f=$self->{base} * 2**(($n-69)/12);
123              
124 6         77 return $f;
125             };
126              
127             =head2 base()
128              
129             =head2 base(FREQ)
130              
131             Sets or gets the base frequency, i.e. the value of A4 (the A above middle C). This defaults to 440 when you create the note object without specifying a base frequency. If called without any parameters, it simply returns the currently set base frequency (from which all other frequencies are calculated). If called with a numeric parameter, then it sets the base frequency to that value and returns the same. If FREQ is not numeric, then it doesn't set anything - it just returns the current base frequency.
132              
133             =cut
134              
135             sub base {
136 1     1 1 1 my $self = shift;
137 1   50     4 my $base = shift || undef;
138              
139 1 50 33     19 if (defined($base) && $base =~ /^\d*\.?\d*$/ && $base =~ /\d/ && $base >= 0) {
      33        
      33        
140 1         3 $self->{base}=$base;
141             }
142 1         4 return $self->{base};
143             }
144              
145              
146             =head1 ACKNOWLEDGEMENTS
147              
148             Special thanks to Ben Daglish, the author of Music::Note L, both for his original module and his suggestion to allow setting the base frequency, and Wikipedia for source material: L.
149              
150              
151             =head1 AUTHOR
152              
153             Mike Kroh, C<< >>
154              
155             =head1 BUGS
156              
157             Please report any bugs or feature requests to C, or through
158             the web interface at L. I will be notified, and then you'll
159             automatically be notified of progress on your bug as I make changes.
160              
161             =head1 TODO
162              
163             Future releases should contain methods to: return frequency in radians/second, return normalized frequencies (given the sampling rate), return frequencies for alternate tunings. Should create methods for different tunings instead of including equal-tempered formula in "frequency()". None of these are a priority at the time of this release.
164              
165              
166             =head1 SUPPORT
167              
168             You can find documentation for this module with the perldoc command.
169              
170             perldoc Music::Note::Frequency
171              
172              
173             You can also look for information at:
174              
175             =over 4
176              
177             =item * RT: CPAN's request tracker (report bugs here)
178              
179             L
180              
181             =item * AnnoCPAN: Annotated CPAN documentation
182              
183             L
184              
185             =item * CPAN Ratings
186              
187             L
188              
189             =item * Search CPAN
190              
191             L
192              
193             =back
194              
195              
196             =head1 LICENSE AND COPYRIGHT
197              
198             Copyright 2016 Mike Kroh.
199              
200             This program is free software; you can redistribute it and/or modify it
201             under the terms of the the Artistic License (2.0). You may obtain a
202             copy of the full license at:
203              
204             L
205              
206             Any use, modification, and distribution of the Standard or Modified
207             Versions is governed by this Artistic License. By using, modifying or
208             distributing the Package, you accept this license. Do not use, modify,
209             or distribute the Package, if you do not accept this license.
210              
211             If your Modified Version has been derived from a Modified Version made
212             by someone other than you, you are nevertheless required to ensure that
213             your Modified Version complies with the requirements of this license.
214              
215             This license does not grant you the right to use any trademark, service
216             mark, tradename, or logo of the Copyright Holder.
217              
218             This license includes the non-exclusive, worldwide, free-of-charge
219             patent license to make, have made, use, offer to sell, sell, import and
220             otherwise transfer the Package with respect to any patent claims
221             licensable by the Copyright Holder that are necessarily infringed by the
222             Package. If you institute patent litigation (including a cross-claim or
223             counterclaim) against any party alleging that the Package constitutes
224             direct or contributory patent infringement, then this Artistic License
225             to you shall terminate on the date that such litigation is filed.
226              
227             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
228             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
229             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
230             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
231             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
232             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
233             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
234             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
235              
236              
237             =cut
238              
239             1; # End of Music::Note::Frequency