File Coverage

blib/lib/Music/PitchNum/ASPN.pm
Criterion Covered Total %
statement 24 24 100.0
branch 9 10 90.0
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 42 43 97.6


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   6177 use 5.010000;
  1         3  
11 1     1   3 use Moo::Role;
  1         1  
  1         5  
12 1     1   619 use POSIX qw/floor/;
  1         4094  
  1         3  
13 1     1   773 use Scalar::Util qw/looks_like_number/;
  1         1  
  1         235  
14              
15             our $VERSION = '0.08';
16              
17             ##############################################################################
18             #
19             # ATTRIBUTES
20              
21             has NOTE2NUM => (
22             is => 'rw',
23             default => sub {
24             { C => 0,
25             D => 2,
26             E => 4,
27             F => 5,
28             G => 7,
29             A => 9,
30             B => 11,
31             };
32             },
33             );
34             has NUM2NOTE => (
35             is => 'rw',
36             default => sub {
37             { 0 => 'C',
38             1 => 'C#',
39             2 => 'D',
40             3 => 'D#',
41             4 => 'E',
42             5 => 'F',
43             6 => 'F#',
44             7 => 'G',
45             8 => 'G#',
46             9 => 'A',
47             10 => 'A#',
48             11 => 'B',
49             };
50             },
51             );
52              
53             has ignore_octave => (
54             is => 'rw',
55             coerce => sub {
56             $_[0] ? 1 : 0;
57             },
58             default => 0,
59             );
60              
61             ##############################################################################
62             #
63             # METHODS
64              
65             sub pitchname {
66 7     7 1 41 my ( $self, $number ) = @_;
67 7 100       25 die "need a number for pitchname\n" if !looks_like_number $number;
68              
69 6 100       25 return $self->NUM2NOTE->{ $number % 12 }
70             . ( $self->ignore_octave ? '' : ( floor( $number / 12 ) - 1 ) );
71             }
72              
73             sub pitchnum {
74 5     5 1 8 my ( $self, $name ) = @_;
75              
76             # already a pitch number, but nix the decimal foo
77 5 50       16 return int $name if looks_like_number $name;
78              
79 5         4 my $pitchnum;
80              
81             # Only sharps, as the Young article only has those. Use the main
82             # module for looser pitch name matching.
83 5 100       25 if ( $name =~ m/ (?[A-G]) (?[#])? (?-?[0-9]{1,2}) /x ) {
84 1     1   395 $pitchnum = 12 * ( $+{octave} + 1 ) + $self->NOTE2NUM->{ $+{note} };
  1         253  
  1         65  
  4         38  
85 4 100       21 $pitchnum++ if defined $+{chrome};
86             }
87              
88 5         17 return $pitchnum;
89             }
90              
91             1;
92             __END__