program PianoNoteByName;
uses sysutils;
var
root12of2, baseFrequency, noteFrequency: real;
noteName: string;
semitoneOffset, octave: integer;
{ Function to convert note name (with optional sharp or flat) to semitone offset from A4 }
function GetSemitoneOffset(note: string; octave: integer): integer;
var
notePart: string;
accidental: char;
noteBaseOffset: integer;
hasAccidental: boolean;
begin
hasAccidental := false;
{ Check if the last character is a sharp (#) or flat (b) }
accidental := note[length(note)];
if (accidental = '#') or (accidental = 'b') then
begin
hasAccidental := true;
notePart := copy(note, 1, length(note) - 1); { All but the last character (for Bb or A#) }
end
else
begin
notePart := note; { The entire note (without accidental) }
end;
{ Base semitone offsets relative to A4 (using C0 as reference) }
if notePart = 'C' then
noteBaseOffset := -9 { C is 9 semitones below A in the same octave }
else if notePart = 'D' then
noteBaseOffset := -7
else if notePart = 'E' then
noteBaseOffset := -5
else if notePart = 'F' then
noteBaseOffset := -4
else if notePart = 'G' then
noteBaseOffset := -2
else if notePart = 'A' then
noteBaseOffset := 0
else if notePart = 'B' then
noteBaseOffset := 2
else
begin
writeln('Error: Invalid note name!');
halt;
end;
{ Adjust for accidentals (sharp '#' or flat 'b') if applicable }
if hasAccidental then
begin
if accidental = 'b' then
noteBaseOffset := noteBaseOffset - 1 { Flat lowers by 1 semitone }
else if accidental = '#' then
noteBaseOffset := noteBaseOffset + 1; { Sharp raises by 1 semitone }
end;
{ Calculate total semitone offset relative to A4 }
GetSemitoneOffset := noteBaseOffset + (octave - 4) * 12;
end;
begin
{ Calculate the 12th root of 2 }
root12of2 := exp(ln(2) / 12);
{ Set the base frequency of A4 (440 Hz) }
baseFrequency := 440.0;
{ Input the note name (e.g., C4, A3, Bb3, A#3) }
writeln('Enter the note (e.g., C4, A3, Bb3, A#3): ');
readln(noteName);
{ Extract the octave from the input (the last character) }
octave := StrToInt(noteName[length(noteName)]); { Last character is the octave number }
{ Calculate the semitone offset from A4, based on the note name and octave }
semitoneOffset := GetSemitoneOffset(copy(noteName, 1, length(noteName) - 1), octave);
{ Calculate the frequency of the note using the semitone offset }
noteFrequency := baseFrequency * exp(ln(root12of2) * semitoneOffset);
{ Output the result }
writeln('The frequency of ', noteName, ' is: ', noteFrequency:0:2, ' Hz');
end.