File Coverage

blib/lib/Music/PitchNum/ASPN.pm
Criterion Covered Total %
statement 25 25 100.0
branch 9 10 90.0
condition 2 2 100.0
subroutine 7 7 100.0
pod 2 2 100.0
total 45 46 97.8


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # Pitch number roles using the American Standard Pitch Notation (ASPN)
4             # format, or something probably close enough.
5             #
6             # Run perldoc(1) on this file for additional documentation.
7              
8             package Music::PitchNum::ASPN;
9              
10 1     1   7662 use 5.010000;
  1         2  
11 1     1   4 use Moo::Role;
  1         1  
  1         5  
12 1     1   758 use POSIX qw/floor/;
  1         5214  
  1         5  
13 1     1   959 use Scalar::Util qw/looks_like_number/;
  1         1  
  1         244  
14              
15             our $VERSION = '0.09';
16              
17             my %NOTE2NUM = (
18             C => 0,
19             D => 2,
20             E => 4,
21             F => 5,
22             G => 7,
23             A => 9,
24             B => 11,
25             );
26              
27             my %NUM2NOTE = (
28             0 => 'C',
29             1 => 'C#',
30             2 => 'D',
31             3 => 'D#',
32             4 => 'E',
33             5 => 'F',
34             6 => 'F#',
35             7 => 'G',
36             8 => 'G#',
37             9 => 'A',
38             10 => 'A#',
39             11 => 'B',
40             );
41              
42             ##############################################################################
43             #
44             # METHODS
45              
46             sub pitchname {
47 7     7 1 10903 my ( $self, $number, %params ) = @_;
48 7 100       32 die "need a number for pitchname\n" if !looks_like_number $number;
49              
50 6   100     22 $params{ignore_octave} //= 0;
51              
52             return $NUM2NOTE{ $number % 12 }
53 6 100       57 . ( $params{ignore_octave} ? '' : ( floor( $number / 12 ) - 1 ) );
54             }
55              
56             sub pitchnum {
57 5     5 1 9 my ( $self, $name ) = @_;
58              
59             # already a pitch number, but nix the decimal foo
60 5 50       20 return int $name if looks_like_number $name;
61              
62 5         6 my $pitchnum;
63              
64             # Only sharps, as the Young article only has those. Use the main
65             # module for looser pitch name matching.
66 5 100       24 if ( $name =~ m/ (?[A-G]) (?[#])? (?-?[0-9]{1,2}) /x ) {
67 1     1   480 $pitchnum = 12 * ( $+{octave} + 1 ) + $NOTE2NUM{ $+{note} };
  1         434  
  1         78  
  4         35  
68 4 100       18 $pitchnum++ if defined $+{chrome};
69             }
70              
71 5         19 return $pitchnum;
72             }
73              
74             1;
75             __END__