[Question]
  [
Quick musical refresher:
The piano keyboard consists of 88 notes. On each octave, there are 12 notes, `C, C♯/D♭, D, D♯/E♭, E, F, F♯/G♭, G, G♯/A♭, A, A♯/B♭` and `B`. Each time you hit a 'C', the pattern repeats an octave higher.
[![enter image description here](https://i.stack.imgur.com/Pu3t5.png)](https://i.stack.imgur.com/Pu3t5.png)
A note is uniquely identified by 1) the letter, including any sharps or flats, and 2) the octave, which is a number from 0 to 8. The first three notes of the keyboard, are `A0, A♯/B♭` and `B0`. After this comes the full chromatic scale on octave 1. `C1, C♯1/D♭1, D1, D♯1/E♭1, E1, F1, F♯1/G♭1, G1, G♯1/A♭1, A1, A♯1/B♭1` and `B1`. After this comes a full chromatic scale on octaves 2, 3, 4, 5, 6, and 7. Then, the last note is a `C8`.
Each note corresponds to a frequency in the 20-4100 Hz range. With `A0` starting at exactly 27.500 hertz, each corresponding note is the previous note times the twelfth root of two, or roughly 1.059463. A more general formula is:
[![enter image description here](https://i.stack.imgur.com/rwSEC.png)](https://i.stack.imgur.com/rwSEC.png)
where n is the number of the note, with A0 being 1. (More information [here](https://en.wikipedia.org/wiki/Piano_key_frequencies))
# The Challenge
Write a program or function that takes in a string representing a note, and prints or returns the frequency of that note. We will use a pound sign `#` for the sharp symbol (or hashtag for you youngins) and a lowercase `b` for the flat symbol. All inputs will look like `(uppercase letter) + (optional sharp or flat) + (number)` with no whitespace. If the input is outside of the range of the keyboard (lower than A0, or higher than C8), or there are invalid, missing or extra characters, this is an invalid input, and you do not have to handle it. You can also safely assume you will not get any weird inputs such as E#, or Cb.
# Precision
Since infinite precision isn't really possible, we'll say that anything within [one cent](https://en.wikipedia.org/wiki/Cent_(music)) of the true value is acceptable. Without going into excess detail, a cent is the 1200th root of two, or 1.0005777895. Let's use a concrete example to make it more clear. Let's say your input was A4. The ***exact*** value of this note is 440 Hz. Once cent flat is `440 / 1.0005777895 = 439.7459`. Once cent sharp is `440 * 1.0005777895 = 440.2542` Therefore, any number greater than 439.7459 but smaller than 440.2542 is precise enough to count.
# Test cases
```
A0  --> 27.500
C4  --> 261.626
F#3 --> 184.997
Bb6 --> 1864.66
A#6 --> 1864.66
A4  --> 440
D9  --> Too high, invalid input.
G0  --> Too low, invalid input.
Fb5 --> Invalid input.
E   --> Missing octave, invalid input
b2  --> Lowercase, invalid input
H#4 --> H is not a real note, invalid input.
```
Keep in mind that you don't have to handle the invalid inputs. If your program pretends they are real inputs and prints out a value, that is acceptable. If your program crashes, that it also acceptable. Anything can happen when you get one. For the full list of inputs and outputs, see [this page](http://www.sengpielaudio.com/calculator-notenames.htm)
As usual, this is code-golf, so standard loopholes apply, and shortest answer in bytes wins.
  
[Answer]
# 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!](http://ethproductions.github.io/japt?v=master&code=NTUqMnBVrK4tMb6qIkMjRCBFRiBHIEEgQiJiWiAvQ30geA==&input=IkE0Ig==)
### 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!)
```
[Answer]
# Pyth, ~~46~~ ~~44~~ ~~43~~ ~~42~~ ~~39~~ 35 bytes
```
*55^2tsm.xsdc-x"C D EF GbA#B"d9 12z
```
[Try it online.](https://pyth.herokuapp.com/?code=*55%5E2%2Btsezc%2B-x%22C%20D%20EF%20G%20A%20B%22hz9-%7D%5C%23z%7D%5Cbz12&input=C4&debug=0) [Test suite.](https://pyth.herokuapp.com/?code=*55%5E2%2Btsezc%2B-x%22C%20D%20EF%20G%20A%20B%22hz9-%7D%5C%23z%7D%5Cbz12&test_suite=1&test_suite_input=A0%0AC4%0AF%233%0ABb6%0AA%236%0AA4&debug=0)
The code now uses a similar algorithm to [ETHproductions's Japt answer](https://codegolf.stackexchange.com/a/69761/30164), 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>
```
[Answer]
# 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 *)
```
[Answer]
# JavaScript ES7, ~~73~~ ~~70~~ 69 bytes
```
x=>[...x].map(c=>t+=c-1.75||"C#D EF G A B".search(c)/12,t=0)&&2**t*55
```
Uses the same technique as my [Japt answer](https://codegolf.stackexchange.com/a/69761/42545).
[Answer]
# [MATL](https://esolangs.org/wiki/MATL), ~~56~~ ~~53~~ ~~50~~ 49 48 bytes
```
Hj1)'C D EF G A B'=f22-'#b'"G@m]-s+ 12/G0)U+^55*
```
Uses [current release (10.1.0)](https://github.com/lmendo/MATL/releases/tag/10.1.0), which is earlier than this challenge.
[**Try it online**!](http://matl.tryitonline.net/#code=SGoxKSdDIEQgRUYgRyBBIEInPWYyMi0nI2InIkdAbV0tcysgMTIvRzApVSteNTUq&input=QmI2)
### Explanation
```
H                   % push 2
j1)                 % get input string. Take first character (note)
'C D EF G A B'=f    % find index of note: 1 for C, 3 for D...
22-                 % subtract 22. This number comes from three parts:
                    % 9; 1 for 0-based indexing; 12 to subtract 1 octave
'#b'"G@m]-s         % For loop. Gives 1 if input contains '#', -1 if 'b', 0 otherwise
+                   % add to previous number. Space needed to separate from next literal
12/                 % divide by 12
G0)                 % push input and get last character (octave)
U+                  % convert to number and add to previous number
^                   % raise 2 (that was initially pushed) to accumulated number 
55*                 % multiply by 55 (=27.5*2). Implicitly display
```
[Answer]
# Ruby, ~~69~~ 65
```
->n{2**((n.ord*13/8%12-n.size+(n=~/#/?7:5))/12.0+n[-1].to_i)*55/4}
```
**Ungolfed in test program**
```
f=->n{
  2**(                    #raise 2 to the power of the following expression:
   (
     n.ord*13/8%12-       #note name C..B maps to number 0..11 calculated from the ascii code of n[0] 
     n.size+(n=~/#/?7:5)  #Correction for flat: length of n is 1 more for flat (or sharp) than for natural. Then apply correction for sharp
                          #now we have a number 3..14 for C..B (so 12 for A, will be a whole number when divided)
   )/12.0+                #divide by 12 to convert into a fraction of an octave
  n[-1].to_i              #add the octave number, last character in n
  )*                      #end of power expression, now we have A0=2,A1=4,A2=4 etc
  55/4                    #multiply to get correct frequency, this is shorter than 13.75 or 440/32                      
}
#complete octave test case
puts %w{A0 A#0 Bb0 B0 C1 C#1 Db1 D1 D#1 Eb1 E1 F1 F#1 Gb1 G1 G#1 Ab1 A1 A#1}.map{|e|[e,f[e]]}
#test case per OP
puts %w{A0 C4 F#3 Bb6 A#6}.map{|e|[e,f[e]]}
```
**Output**
```
A0
27.5
A#0
29.13523509488062
Bb0
29.13523509488062
B0
30.867706328507758
C1
32.70319566257483
C#1
34.64782887210901
Db1
34.64782887210901
D1
36.70809598967595
D#1
38.890872965260115
Eb1
38.890872965260115
E1
41.20344461410875
F1
43.653528929125486
F#1
46.2493028389543
Gb1
46.2493028389543
G1
48.999429497718666
G#1
51.91308719749314
Ab1
51.91308719749314
A1
55.0
A#1
58.27047018976123
A0
27.5
C4
261.6255653005986
F#3
184.9972113558172
Bb6
1864.6550460723593
A#6
1864.6550460723593
```
[Answer]
# ES7, 82 bytes
```
s=>55*2**(+s.slice(-1)+("C D EF G A B".search(s[0])+(s[1]<'0')-(s[1]>'9')-21)/12)
```
Returns 130.8127826502993 on input of "B#2" as expected.
Edit: Saved 3 bytes thanks to @user81655.
[Answer]
# 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
}
```
[Answer]
# R, ~~157~~ ~~150~~ ~~141~~ 136 bytes
```
f=function(x){y=strsplit(x,"")[[1]];55*2^(as.double(y[nchar(x)])-1+(c(10,12,1,3,5,6,8)[LETTERS==y[1]]-switch(y[2],"#"=9,"b"=11,10))/12)}
```
With indent and newlines:
```
f=function(x){
     y=strsplit(x,"")[[1]]
     55 * 2^(as.double(y[nchar(x)]) - 1 + 
         (c(10,12,1,3,5,6,8)[LETTERS==y[1]] - 
         switch(y[2],"#"=9,"b"=11,10))/12)
     }
```
Usage:
```
> f("A0")
[1] 27.5
> f("C8")
[1] 4186.009
> sapply(c("C4","Bb6","A#6","A4"),f)
       C4       Bb6       A#6        A4 
 261.6256 1864.6550 1864.6550  440.0000 
```
[Answer]
# Python, ~~97~~ 95 bytes
```
def f(n):a,*b,c=n;return 2**(int(c)+('C@D@EF@G@A@B'.find(a)-(21,(22,20)['#'in b])[b>[]])/12)*55
```
Based on Pietu1998's (and others') old approach of looking for the index of the note in the string `'C@D@EF@G@A@B'` for some blank char or another. I use iterable unpacking to parse the note string without conditionals. I did a little bit of algebra at the end to simplify the conversion expression. Don't know if I can get it shorter without changing my approach.
[Answer]
# Wolfram Language (Mathematica), 69 bytes
```
ToExpression@("Music`"<>StringReplace[#,{"b"->"flat","#"->"sharp"}])&
```
Using the [music package](http://reference.wolfram.com/language/Music/guide/MusicPackage.html), with which simply entering a note as an expression evaluates to its frequency, like this:
```
 In[1]:= Eflat3
Out[1]:= 155.563
```
To save bytes by avoiding to import the package with `<<Music`, I'm using the fully qualified names: `Music`Eflat3`. However, I still have to replace `b` with `flat` and `#` with `sharp` to match the input format of the question, which I do with a simple `StringReplace`.
]