C, 123 bytes
float d(char*s){int n=*s++,m=(n*12+(n<67?90:6))/7,o=*s++,a=o^35?o^98?0:-1:1;return exp((m+(a?*s++:o)*12+a)/17.3123-37.12);}
Usage:
#include <stdio.h>
#include <math.h>
float d(char*s){int n=*s++,m=(n*12+(n<67?90:6))/7,o=*s++,a=o^35?o^98?0:-1:1;return exp((m+(a?*s++:o)*12+a)/17.3123-37.12);}
int main()
{
printf("%f\n", d("A4"));
}
The calculated value is always about 0.8 cents less than the exact value, because I cut as many digits as possible from the floating-point numbers.
Overview of the code:
float d(char*s){
{
int n=*s++, // read the letter
m=(n*12+ // multiply by 12/7 to convert from A...G to 0...11
(n<67?90:6) // if A or B, add 1 octave; also add some fix-up rounding value
)/7,
o=*s++, // read next char: the octave digit or accidental
a=o^35?o^98?0:-1:1; // if accidental, convert it into +1 or -1; else 0
return exp((m+ // I adjusted the factors to use exp instead of pow
(a?*s++:o) // if was accidental, now read the octave digit
*12+a)/
17.3123- // a more exact value is 17.3123404447
37.12); // a more exact value is 37.1193996632
}