[Tex/LaTex] Range of a piano : annotate note frequency

music

I'd like to draw something like this for the piano, but with all notes explicitly draw and labelled with its frequency. I use for the first time the musixtex package so I have no idea how to automate the annotation.

Here is what I've done so far.

\documentclass[preview,border={3cm 2mm 3cm 2mm}]{standalone}% standalone works with adjusting the border.
\usepackage{musixtex}
\begin{document}
\begin{music}
\instrumentnumber{1}
\setstaffs{1}{2}
\setclef{1}{60}
%
\startextract
\notes\qu{`CDEFG 'AB}\enotes
\bar
\notes\qu{CDEFG 'AB}\enotes
\bar
\notes\qu{'CDEFG 'AB}\enotes
\bar
\notes|\qu{cdefg'ab}\enotes
\bar
\notes|\qu{'cdefg 'ab}\enotes
\zendextract
\end{music}
\end{document}

enter image description here

Best Answer

I'm not sure if I understood the question right and this is what you want but here we go: the code uses the fact that a pitch cannot only be specified with a letter but also with a number. The frequencies are calculated with the formula on the linked Wikipedia site. (I don't know why the margins for standalone have to be enlarged manually to see the whole extract...).

% arara: musixtex
\documentclass[preview,border={17cm 2mm 17cm 2mm}]{standalone}
\usepackage[T1]{fontenc}
\usepackage{musixtex}
\usepackage{xcolor}
\usepackage{expl3,xparse}
\ExplSyntaxOn
% define integer variables:
\int_new:N \l__cjorssen_pitch_int
\int_new:N \l__cjorssen_step_int

% define tokenlist variable for the formatted output of the
% frequencies:
\tl_new:N  \l__cjorssen_freq_format_tl
\tl_set:Nn \l__cjorssen_freq_format_tl { \tiny\bfseries }

% macro to write notes and frequencies for one octave
%   #1: the lowest pitch
%   #2: the highest pitch, should not be more than #1+6
%   #3: the difference between pitch number and key number
\cs_new_protected:Npn \cjorssen_write_notes:nnn #1#2#3
  {
    % set the starting pitch:
    \int_set:Nn \l__cjorssen_pitch_int { #1 }
    % set the step to zero:
    \int_zero:N \l__cjorssen_step_int
    % loop until we reach the end pitch:
    \int_do_while:nn { \l__cjorssen_pitch_int <= #2 }
      {
        % \cchar{<pitch>}{<something>} is a musixtex macro that
        % allows setting <something> at the specified <pitch>
        % let's set the frequency below the tone it belongs to:
        \cchar
          { \int_eval:n { \l__cjorssen_pitch_int - 5 } }
          {
            % start a group to keep the format local, just in case
            \group_begin:
              % the format:
              \tl_use:N \l__cjorssen_freq_format_tl
              % let's test at which point of the octave we are
              % and add the needed integer to \l__cjorssen_pitch_int
              % in order to get the right key number with respect to
              % musixtex's pitch number:
              \int_case:nnn { \l__cjorssen_step_int }
                {
                  { 0 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + #3 } }
                  { 1 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 1 + #3 } }
                  { 2 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 2 + #3 } }
                  { 3 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 2 + #3 } }
                  { 4 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 3 + #3 } }
                  { 5 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 4 + #3 } }
                  { 6 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 5 + #3 } }
                }
                {}
              \,Hz
            \group_end:
          }
        % write the note:
        \qu { \int_use:N \l__cjorssen_pitch_int }
        % step the integers for the next round in the loop:
        \int_incr:N \l__cjorssen_step_int
        \int_incr:N \l__cjorssen_pitch_int
      }
  }

% calculate the frequency from the key number
% (using 440Hz for the concert pitch):
\cs_new:Npn \cjorssen_calc_freq:n #1
  { \fp_eval:n { round ( 440 * 2^(((#1)-49)/12) , 2 ) } }

% #1: the lowest pitch
% #2: the highest pitch, should not be more than #1+6
% #3: the difference between pitch number and key number
\NewDocumentCommand \writenotes { mO{#1+6}m }
  { \cjorssen_write_notes:nnn { #1 } { #2 } { #3 } }
\ExplSyntaxOff
\begin{document}
\noindent
\begin{music}
 \instrumentnumber{1}
 \setstaffs{1}{2}
 \setclef{1}{60}
 \setname{1}{}
 \startextract
 \NOTes
  \writenotes{-11}{15}
 \en\bar
 \NOTes
  \writenotes{-4}{20}
 \en\bar
 \NOTes
  \writenotes{3}{25}
 \en\bar
 \NOTEs|
  \writenotes{-2}{42}
 \en\bar
 \NOTEs|
  \writenotes{5}{47}
 \en
 \endextract
\end{music}
\end{document}

enter image description here

Here is the same with the article class:

% arara: musixtex
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{musixtex}
\usepackage{xcolor}
\usepackage{expl3,xparse}
\ExplSyntaxOn
% define integer variables:
\int_new:N \l__cjorssen_pitch_int
\int_new:N \l__cjorssen_step_int

% define tokenlist variable for the formatted output of the
% frequencies:
\tl_new:N  \l__cjorssen_freq_format_tl
\tl_set:Nn \l__cjorssen_freq_format_tl { \tiny\bfseries }

% macro to write notes and frequencies for one octave
%   #1: the lowest pitch
%   #2: the highest pitch, should not be more than #1+6
%   #3: the difference between pitch number and key number
\cs_new_protected:Npn \cjorssen_write_notes:nnn #1#2#3
  {
    % set the starting pitch:
    \int_set:Nn \l__cjorssen_pitch_int { #1 }
    % set the step to zero:
    \int_zero:N \l__cjorssen_step_int
    % loop until we reach the end pitch:
    \int_do_while:nn { \l__cjorssen_pitch_int <= #2 }
      {
        % \cchar{<pitch>}{<something>} is a musixtex macro that
        % allows setting <something> at the specified <pitch>
        % let's set the frequency below the tone it belongs to:
        \cchar
          { \int_eval:n { \l__cjorssen_pitch_int - 5 } }
          {
            % start a group to keep the format local, just in case
            \group_begin:
              % the format:
              \tl_use:N \l__cjorssen_freq_format_tl
              % let's test at which point of the octave we are
              % and add the needed integer to \l__cjorssen_pitch_int
              % in order to get the right key number with respect to
              % musixtex's pitch number:
              \int_case:nnn { \l__cjorssen_step_int }
                {
                  { 0 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + #3 } }
                  { 1 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 1 + #3 } }
                  { 2 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 2 + #3 } }
                  { 3 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 2 + #3 } }
                  { 4 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 3 + #3 } }
                  { 5 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 4 + #3 } }
                  { 6 } { \cjorssen_calc_freq:n { \l__cjorssen_pitch_int + 5 + #3 } }
                }
                {}
              \,Hz
            \group_end:
          }
        % write the note:
        \qu { \int_use:N \l__cjorssen_pitch_int }
        % step the integers for the next round in the loop:
        \int_incr:N \l__cjorssen_step_int
        \int_incr:N \l__cjorssen_pitch_int
      }
  }

% calculate the frequency from the key number
% (using 440Hz for the concert pitch):
\cs_new:Npn \cjorssen_calc_freq:n #1
  { \fp_eval:n { round ( 440 * 2^(((#1)-49)/12) , 2 ) } }

% #1: the lowest pitch
% #2: the highest pitch, should not be more than #1+6
% #3: the difference between pitch number and key number
\NewDocumentCommand \writenotes { mO{#1+6}m }
  { \cjorssen_write_notes:nnn { #1 } { #2 } { #3 } }
\ExplSyntaxOff
\begin{document}
\noindent
\begin{music}
 \instrumentnumber{1}
 \setstaffs{1}{2}
 \setclef{1}{60}
 \setname{1}{}
 \startpiece
 \NOTes
  \writenotes{-11}{15}
 \en\alaligne
 \NOTes
  \writenotes{-4}{20}
 \en\alaligne
 \NOTes
  \writenotes{3}{25}
 \en\alaligne
 \NOTEs|
  \writenotes{-2}{42}
 \en\alaligne
 \NOTEs|
  \writenotes{5}{47}
 \en
 \endpiece
\end{music}
\end{document}

enter image description here

Related Question