package ComputerMusic; #ComputerMusic.pm - Useful computer music related functions #Copyright (C) 2001 Jacob T. Joaquin # #This program is free software; you can redistribute it and/or #modify it under the terms of the GNU General Public License #as published by the Free Software Foundation; either version 2 #of the License, or (at your option) any later version. # #This program is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #GNU General Public License for more details. # #You should have received a copy of the GNU General Public License #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use strict; sub harmonic { # return a relative harmonic of a frequency my $frequency = shift; # The frequency my $relative = shift; # Relative Harmonic Ratio of the frequency my $destination = shift; # Destination Harmonic of the returned frequency my $bend = shift; # Detune amount of the returned frequency if (defined($bend)) { return $frequency * $destination / $relative * $bend; } else { return $frequency * $destination / $relative; } } sub interpolate { my $position = shift; # location of pointer in interpolation my $point0 = shift; # start point of interpolation my $point1 = shift; # end point of interpolation my $scale0 = shift; # scale bias my $scale1 = shift; # scale bias my $result; $result = ($position - $point0) / ($point1 - $point0); return $result * ($scale1 - $scale0) + $scale0; } sub interpolateExp { my $position = shift; my $point0 = shift; my $point1 = shift; my $scale0 = shift; my $scale1 = shift; my $amt = shift; my $result; $result = ($position - $point0) / ($point1 - $point0); $result = (($result + 1) ** $amt) - 1; $result = $result/((2 ** $amt)-1); return $result * ($scale1 - $scale0) + $scale0; } sub pitchToFreq { my $STEP = 1.0594630943593; my $octave = shift; my $note = shift; my $t; if ($octave >= 8) { $t = ($octave - 7) * 440 } if ($octave < 8) { $t = 440 / (2 ** (8 - $octave)) } if($note > 9){ for(1..$note-9) { $t *= $STEP } } elsif ($note < 9) { for(1..9-$note) { $t /= $STEP } } return $t; } 1;