File Coverage

blib/lib/Lutherie/FretCalc.pm
Criterion Covered Total %
statement 6 159 3.7
branch 0 96 0.0
condition 0 24 0.0
subroutine 2 15 13.3
pod 13 13 100.0
total 21 307 6.8


line stmt bran cond sub pod time code
1             # Copyright (c) 2001 Douglas Sparling. All rights reserved. This program is free
2             # software; you can redistribute it and/or modify it under the same terms
3             # as Perl itself.
4              
5             package Lutherie::FretCalc;
6              
7 1     1   788 use strict;
  1         2  
  1         43  
8 1     1   5 use vars qw($VERSION);
  1         1  
  1         1624  
9              
10             $VERSION = '0.33';
11              
12             sub new {
13 0     0 1   my $proto = shift;
14 0   0       my $class = ref($proto) || $proto;
15 0           my $self = {};
16              
17 0 0         if (defined $_[0]) {
18 0           $self->{scale} = $_[0];
19             } else {
20 0           $self->{scale} = 25;
21             }
22 0 0         if (defined $_[1]) {
23 0           $self->{num_frets} = $_[1];
24             } else {
25 0           $self->{num_frets} = 24;
26             }
27             #$self->{num_frets} = 24;
28 0           $self->{fret_num} = 12;
29 0           $self->{in_units} = 'in';
30 0           $self->{out_units} = 'in';
31 0           $self->{calc_method} = 't';
32 0           $self->{tet} = 12;
33 0           $self->{precision} = 4; # Precision for 'in'
34             #$self->{half_fret} = ();
35              
36 0           bless($self, $class);
37 0           return $self;
38             }
39              
40             sub scale {
41 0     0 1   my($self) = shift;
42 0 0         if(@_) { $self->{scale} = shift }
  0            
43 0           return $self->{scale};
44             }
45              
46             sub num_frets {
47 0     0 1   my($self) = shift;
48 0 0         if(@_) { $self->{num_frets} = shift }
  0            
49 0           return $self->{num_frets};
50             }
51              
52             sub fret_num {
53 0     0 1   my($self) = shift;
54 0 0         if(@_) { $self->{fret_num} = shift }
  0            
55 0           return $self->{fret_num};
56             }
57              
58             sub in_units {
59 0     0 1   my($self) = shift;
60 0 0         if(@_) { $self->{in_units} = shift }
  0            
61 0           return $self->{in_units};
62             }
63              
64             sub out_units {
65 0     0 1   my($self) = shift;
66 0 0         if(@_) {
67 0           my $out_units = shift;
68             # Set precision defaults
69 0 0         if( $out_units eq 'in' ) {
70 0           $self->{precision} = 4;
71             } else {
72 0           $self->{precision} = 1;
73             }
74 0           $self->{out_units} = $out_units;
75             }
76 0           return $self->{out_units};
77             }
78              
79             sub calc_method {
80 0     0 1   my($self) = shift;
81 0 0         if(@_) { $self->{calc_method} = shift }
  0            
82 0           return $self->{calc_method};
83             }
84              
85             sub tet {
86 0     0 1   my($self) = shift;
87 0 0         if(@_) { $self->{tet} = shift }
  0            
88 0           return $self->{tet};
89             }
90              
91             sub precision {
92 0     0 1   my($self) = shift;
93 0 0         if(@_) {
94 0           my $prec = shift;
95 0 0 0       $prec = 4 if $prec < 0 or $prec > 6;
96 0           $self->{precision} = $prec;
97             }
98 0           return $self->{precision};
99             }
100              
101             sub half_fret {
102 0     0 1   my($self) = shift;
103             #if(@_) { $self->{half_fret} = shift }
104 0 0         if(@_) {
105 0 0         if($self->{half_fret}) {
106 0           $self->{half_fret} = join(',', $self->{half_fret},shift);
107             } else {
108 0           $self->{half_fret} = shift;
109             }
110             }
111 0           return $self->{half_fret};
112             }
113              
114              
115             sub fretcalc {
116              
117 0     0 1   my($self) = shift;
118              
119 0 0         if(@_) { $self->{num_frets} = shift }
  0            
120              
121 0           my $distance_from_nut = 0;
122 0           my $distance_from_nut_formatted;
123              
124 0           my @chart = ();
125             # Set precision
126 0           my $prec;
127 0 0         $prec = '%8.0f' if $self->{precision} == 0;
128 0 0         $prec = '%8.1f' if $self->{precision} == 1;
129 0 0         $prec = '%8.2f' if $self->{precision} == 2;
130 0 0         $prec = '%8.3f' if $self->{precision} == 3;
131 0 0         $prec = '%8.4f' if $self->{precision} == 4;
132 0 0         $prec = '%8.5f' if $self->{precision} == 5;
133 0 0         $prec = '%8.6f' if $self->{precision} == 6;
134 0           $chart[0] = sprintf("$prec",0);
135              
136 0           for my $i (1..$self->{num_frets}) {
137 0 0         if ($self->{calc_method} eq 't') {
    0          
    0          
    0          
138 0           $distance_from_nut = ($self->{scale} - $self->{scale}/2 ** ($i/$self->{tet}));
139             } elsif ($self->{calc_method} eq 'ec') {
140 0           my $x = ($self->{scale} - $distance_from_nut) / 17.817;
141 0           $distance_from_nut += $x;
142             } elsif ($self->{calc_method} eq 'es') {
143 0           my $x = ($self->{scale} - $distance_from_nut) / 17.835;
144 0           $distance_from_nut += $x;
145             } elsif ($self->{calc_method} eq 'ep') {
146 0           my $x = ($self->{scale} - $distance_from_nut) / 18;
147 0           $distance_from_nut += $x;
148             } else {
149 0           $distance_from_nut = ($self->{scale} - $self->{scale}/2 ** ($i/12));
150             }
151              
152             ### input scale: in, output scale: in
153 0 0 0       if( ($self->{in_units} eq 'in') && ($self->{out_units} eq 'in') ) {
    0 0        
    0 0        
154 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
155             ### input scale: in, output scale: mm
156             } elsif( ($self->{in_units} eq 'in') && ($self->{out_units} eq 'mm') ) {
157 0           $distance_from_nut *= 25.4;
158 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
159             ### input scale: mm, output scale: in
160             } elsif( ($self->{in_units} eq 'mm') && ($self->{out_units} eq 'in') ) {
161 0           $distance_from_nut /= 25.4;
162 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
163             #### input scale: mm, out_units: mm
164             } else {
165 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
166             }
167 0           push @chart, $distance_from_nut_formatted;
168             }
169              
170 0           return @chart;
171              
172             }
173              
174             sub fret {
175              
176 0     0 1   my $self = shift;
177              
178             # Check if fret_num was passed
179 0 0         if(@_) { $self->{fret_num} = shift }
  0            
180              
181             # Set precision
182 0           my $prec;
183 0 0         $prec = '%8.0f' if $self->{precision} == 0;
184 0 0         $prec = '%8.1f' if $self->{precision} == 1;
185 0 0         $prec = '%8.2f' if $self->{precision} == 2;
186 0 0         $prec = '%8.3f' if $self->{precision} == 3;
187 0 0         $prec = '%8.4f' if $self->{precision} == 4;
188 0 0         $prec = '%8.5f' if $self->{precision} == 5;
189 0 0         $prec = '%8.6f' if $self->{precision} == 6;
190              
191 0           my $distance_from_nut = 0;
192 0           my $distance_from_nut_formatted;
193 0 0         if ($self->{calc_method} eq 't') {
    0          
    0          
    0          
194 0           $distance_from_nut = ($self->{scale} - $self->{scale}/2 ** ($self->{fret_num}/$self->{tet}));
195             } elsif ($self->{calc_method} eq 'ec') {
196 0           for my $i (1..$self->{fret_num}) {
197 0           my $x = ($self->{scale} - $distance_from_nut) / 17.817;
198 0           $distance_from_nut += $x;
199             }
200             } elsif ($self->{calc_method} eq 'es') {
201 0           for my $i (1..$self->{fret_num}) {
202 0           my $x = ($self->{scale} - $distance_from_nut) / 17.835;
203 0           $distance_from_nut += $x;
204             }
205             } elsif ($self->{calc_method} eq 'ep') {
206 0           for my $i (1..$self->{fret_num}) {
207 0           my $x = ($self->{scale} - $distance_from_nut) / 18;
208 0           $distance_from_nut += $x;
209             }
210             } else {
211 0           $distance_from_nut = ($self->{scale} - $self->{scale}/2 ** ($self->{fret_num}/$self->{tet}));
212             }
213              
214             ### in_units: in, out_units: in
215 0 0 0       if( ($self->{in_units} eq 'in') && ($self->{out_units} eq 'in') ) {
    0 0        
    0 0        
216 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
217             ### in_units: in, out_units: mm
218             } elsif( ($self->{in_units} eq 'in') && ($self->{out_units} eq 'mm') ) {
219 0           $distance_from_nut *= 25.4;
220 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
221             ### in_units: mm, out_units: in
222             } elsif( ($self->{in_units} eq 'mm') && ($self->{out_units} eq 'in') ) {
223 0           $distance_from_nut /= 25.4;
224 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
225             ### in_units: mm, out_units: mm
226             } else {
227 0           $distance_from_nut_formatted = sprintf("$prec",$distance_from_nut);
228             }
229 0           return $distance_from_nut_formatted;
230              
231             }
232              
233             sub dulc_calc {
234 0     0 1   my($self) = shift;
235 0           my %dulc;
236 0           my @frets = $self->fretcalc(24); # Use 24 frets for dulcimer
237              
238             # Set standard frets
239 0           $dulc{1} = $frets[2];
240 0           $dulc{2} = $frets[4];
241 0           $dulc{3} = $frets[5];
242 0           $dulc{4} = $frets[7];
243 0           $dulc{5} = $frets[9];
244 0           $dulc{6} = $frets[10];
245 0           $dulc{7} = $frets[12];
246              
247 0           $dulc{8} = $frets[14];
248 0           $dulc{9} = $frets[16];
249 0           $dulc{10} = $frets[17];
250 0           $dulc{11} = $frets[19];
251 0           $dulc{12} = $frets[21];
252 0           $dulc{13} = $frets[22];
253 0           $dulc{14} = $frets[24];
254              
255             # Add the half frets (valid = 1,6,8,13)
256 0           my @half_frets = split(/,/,$self->{half_fret});
257 0           foreach my $half( @half_frets ) {
258 0 0         if( $half == 1 ) {
    0          
    0          
    0          
259 0           $dulc{1.5} = $frets[3];
260             } elsif( $half == 6 ) {
261 0           $dulc{6.5} = $frets[11];
262             } elsif( $half == 8 ) {
263 0           $dulc{8.5} = $frets[15];
264             } elsif( $half == 13 ) {
265 0           $dulc{13.5} = $frets[23];
266             }
267             }
268              
269 0           return %dulc;
270              
271             }
272              
273              
274             1;
275              
276             __END__