What is the frequency of this note?
Japt, 41 37 35 34 bytes
I finally have a chance to put ¾
to good use! :-)
55*2pU¬®-1¾ª"C#D EF G A B"bZ /C} x
Try it online!
How it works
// Implicit: U = input string, C = 12
U¨ } // Take U, split into chars, and map each item Z by this function:
-1¾ // Subtract 1.75 from Z. This produces NaN for non-digits.
ª"..."bZ // If the result is falsy (NaN), instead return the index of Z in this string.
// C produces 0, D -> 2, E -> 4, F -> 5, G -> 7, A -> 9, B -> 11.
// # -> 1, and b -> -1, so we don't need to calculate them separately.
/C // Divide the index by 12.
x // Sum.
2p // Take 2 to the power of the result.
55* // Multiply by 55.
Test cases
All the valid test cases come through fine. It's the invalid ones where it gets weird...
input --> output (program's reasoning)
A0 --> 27.5 (Yep, I can do that for you!)
C4 --> 261.625565... (Yep, I can do that for you!)
F#3 --> 184.997211... (Yep, I can do that for you!)
Bb6 --> 1864.6550... (Yep, I can do that for you!)
A#6 --> 1864.6550... (Yep, I can do that for you!)
A4 --> 440 (Yep, I can do that for you!)
D9 --> 9397.27257... (Who says that's too high?)
G0 --> 24.49971... (I've heard that note before.)
Fb5 --> 659.25511... (Wait, Fb isn't supposed to be a note?)
E --> 69.295657... (I'm gonna guess that the missing octave is 1¾.)
b2 --> 61.735412... (I assume that b means Cb...)
H#4 --> 261.625565... (H# is C!)
Pyth, 46 44 43 42 39 35 bytes
*55^2tsm.xsdc-x"C D EF GbA#B"d9 12z
Try it online. Test suite.
The code now uses a similar algorithm to ETHproductions's Japt answer, so credit to him for that.
Explanation
implicit: z = input
m z for each character in input:
sd try parsing as number
.x if that fails:
"C D EF GbA#B" string "C D EF GbA#B"
x d find index of character in that
- 9 subtract 9
c 12 divide by 12
s sum results
t decrement
^2 get the correct power of 2
*55 multiply by 55 (frequency of A1)
Old version (42 bytes, 39 w/ packed string)
*55^2+tsezc+-x"C D EF G A B"hz9-}\#z}\bz12
Explanation
<pre>
implicit: z = input
GET OFFSET BY NOTE:
."…" string "C@D@EF@G@A@B" packed
x hz get index of first char in input
- 9 subtract 9
PARSE #/b:
+ }\#z add 1 if input contains "#"
- }\bz subtract 1 if input contains "b"
CONVERT OFFSET TO OCTAVES:
c 12 divide by 12
FIND OCTAVE IN INPUT:
ez last char of input
s convert to number
GET FINAL RESULT:
t decrement the octave
+ add the octave and the note offset
^2 get the correct power of 2
*55 multiply by 55 (frequency of A1)
</pre>
Mathematica, 77 bytes
2^((Import[".mid"~Export~Sound@SoundNote@#,"RawData"][[1,3,3,1]]-69)/12)440.&
Explanation:
The main idea of this function is to convert the string of note to its relative pitch, and then calculate its frequency.
The method I use is export the sound to midi and import the raw data, but I suspect that there is a more elegant way.
Test cases:
f=%; (* assign the function above to f *)
f["A4"] (* 440. *)
f["A5"] (* 880. *)
f["C#-1"] (* 8.66196 *)
f["Fb4"] (* 329.628 *)
f["E4"] (* 329.628 *)
f["E"] (* 329.628 *)