Recent

Author Topic: Pascal and Musical Tones :D  (Read 14572 times)

OC DelGuy

  • Full Member
  • ***
  • Posts: 218
  • 123
Pascal and Musical Tones :D
« on: January 02, 2025, 01:49:11 am »
I got this little bit of code from Chat GPT and it works fine.  Everything in the code block is ChatGPT except that I changed and added to the note values (ChatGPT only gave Hz values[and only 500, 1000, 1500, 2000 and 3000]).  I added the notes (letters) and changed their respective Hz's and I added the additional nine notes.  And I added the last procedure "DoReMi".

I'm having trouble with Beeps not playing.  It's just 4 Beeps, but only 3 play.  I know that all 4 notes actually play because when I play them using the BeepButton, they play.  The first Beep is getting skipped.

Also, the Label.Caption line seems to be getting skipped.  Only the last Caption shows("Fa").

I thought the Label.Caption would change and then the  BeepAtFrequency would play the respective beep frequency.  Right now it just plays the last 3 beeps and :o THEN :o changes the Caption!
You're killing me, Lazzy! %) :P

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, Windows;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     BeepButton: TButton;
  16.     DoReMi: TButton;
  17.     FrequencyComboBox: TComboBox;
  18.     FrequencyLabel: TLabel;
  19.     procedure DoReMiClick(Sender: TObject);
  20.     procedure FormCreate(Sender: TObject);
  21.     procedure BeepButtonClick(Sender: TObject);
  22.   private
  23.  
  24.   public
  25.  
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. {$R *.lfm}
  34.  
  35. { TForm1 }
  36.  
  37. procedure TForm1.FormCreate(Sender: TObject);
  38. begin
  39.   // Populate the frequency combo box with different values (in Hertz).
  40.   FrequencyComboBox.Items.Add('C4      - 261.63 Hz');
  41.   FrequencyComboBox.Items.Add('C#4/Db4 - 277.18 Hz');
  42.   FrequencyComboBox.Items.Add('D4      - 293.66 Hz');
  43.   FrequencyComboBox.Items.Add('D#4/Eb4 - 311.13 Hz');
  44.   FrequencyComboBox.Items.Add('E4      - 329.63 Hz');
  45.   FrequencyComboBox.Items.Add('F4      - 349.23 Hz');
  46.   FrequencyComboBox.Items.Add('F#4/Gb4 - 369.99 Hz');
  47.   FrequencyComboBox.Items.Add('G4      - 392.00 Hz');
  48.   FrequencyComboBox.Items.Add('G#4/Ab4 - 415.30 Hz');
  49.   FrequencyComboBox.Items.Add('A4      - 440.00 Hz');
  50.   FrequencyComboBox.Items.Add('A#4/Bb4 - 466.16 Hz');
  51.   FrequencyComboBox.Items.Add('B4      - 493.88 Hz');
  52.   FrequencyComboBox.Items.Add('C5      - 523.25 Hz');
  53.   // Set a default selection
  54.   FrequencyComboBox.ItemIndex := 0;
  55.  
  56.   // Update the label to show the selected frequency
  57.   FrequencyLabel.Caption := 'Frequency: 261.63 Hz';
  58.  
  59. end;
  60.  
  61. // Procedure to generate a beep at the given frequency (in Hz)
  62. procedure BeepAtFrequency(Frequency: Integer);
  63. begin
  64.   // Use the Windows Beep function to play the beep sound
  65.   Beep(Frequency, 500);  // 500 milliseconds duration
  66. end;
  67.  
  68. procedure TForm1.BeepButtonClick(Sender: TObject);
  69. var
  70.   Frequency: Integer;
  71. begin
  72.   // Get the selected frequency from the combo box
  73.   case FrequencyComboBox.ItemIndex of
  74.     0: Frequency := 261;
  75.     1: Frequency := 277;
  76.     2: Frequency := 293;
  77.     3: Frequency := 311;
  78.     4: Frequency := 329;
  79.     5: Frequency := 349;
  80.     6: Frequency := 369;
  81.     7: Frequency := 392;
  82.     8: Frequency := 415;
  83.     9: Frequency := 440;
  84.    10: Frequency := 466;
  85.    11: Frequency := 493;
  86.    12: Frequency := 523;
  87.   else
  88.     Frequency := 261;     // Default to 261 Hz
  89.   end;
  90.  
  91.   // Update the label to show the frequency
  92.   FrequencyLabel.Caption := 'Frequency: ' + IntToStr(Frequency) + ' Hz';
  93.  
  94.   // Generate the beep with the selected frequency
  95.   BeepAtFrequency(Frequency);
  96. end;
  97.  
  98. procedure TForm1.DoReMiClick(Sender: TObject);
  99. begin
  100.   FrequencyLabel.Caption := 'Do';
  101.   BeepAtFrequency(261);
  102.  
  103.   FrequencyLabel.Caption := 'Re';
  104.   BeepAtFrequency(293);
  105.  
  106.   FrequencyLabel.Caption := 'Mi';
  107.   BeepAtFrequency(329);
  108.  
  109.   FrequencyLabel.Caption := 'Fa';
  110.   BeepAtFrequency(349);
  111.  
  112. end;
  113.  
  114.  
  115. end.
  116.  
Free Pascal Lazarus Version #: 2.2.4
Date: 24 SEP 2022
FPC Version: 3.2.2
Revision: Lazarus_2_2_4
x86_64-win64-win32/win64

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #1 on: January 02, 2025, 02:00:09 am »
Hello.

Maybe try adding application.processmessages ? :

Code: Pascal  [Select][+][-]
  1. procedure TForm1.DoReMiClick(Sender: TObject);
  2. begin
  3.   FrequencyLabel.Caption := 'Do';
  4.   BeepAtFrequency(261);
  5.   application.processmessages;
  6.  
  7.   FrequencyLabel.Caption := 'Re';
  8.   BeepAtFrequency(293);
  9.   application.processmessages;
  10.  
  11.   FrequencyLabel.Caption := 'Mi';
  12.   BeepAtFrequency(329);
  13.   application.processmessages;
  14.  
  15.   FrequencyLabel.Caption := 'Fa';
  16.   BeepAtFrequency(349);
  17.   application.processmessages;
  18. end;

Quote
Everything in the code block is ChatGPT except that I changed and added to the note values (ChatGPT only gave Hz values[and only 500, 1000, 1500, 2000 and 3000]).
You should ask it to uos:

Code: Pascal  [Select][+][-]
  1. const
  2.   // musical note ==> frequency in hertz
  3.   // Latin: Do, Ré, Mi, Fa, Sol, La, Si
  4.   // Dièse = _d example la0_d
  5.   la0  = 55.0;
  6.   la0_d = 58.3;
  7.   si0 = 61.7;
  8.   do0 =  65.4;
  9.   do0_d = 69.3;
  10.   re0 = 73.4;
  11.   re0_d = 77.8;
  12.   mi0  = 82.4;
  13.   fa0  = 87.3;
  14.   fa0_d = 92.5;
  15.   sol0 = 98.0;
  16.   sol0_d = 103.8;
  17.   la1  = 110.0;
  18.   la1_d = 116.5;
  19.   si1 = 123.5;
  20.   do1 =  130.8;
  21.   do1_d = 138.6;
  22.   re1 = 146.8;
  23.   re1_d = 155.6;
  24.   mi1  = 164.8;
  25.   fa1  = 174.6;
  26.   fa1_d = 185.0;
  27.   sol1 = 196.0;
  28.   sol1_d = 207.7;
  29.   la2 = 220.0;
  30.   la2_d = 233.1;
  31.   si2 = 2246.9;
  32.   do2 =  261.6;
  33.   do2_d = 277.2;
  34.   re2 = 293.7;
  35.   re2_d = 311.1;
  36.   mi2  = 329.6;
  37.   fa2  = 349.2;
  38.   fa2_d = 370.0;
  39.   sol2 = 392.0;
  40.   sol2_d = 415.3;
  41.   la3  = 440.0;
  42.   la3_d = 466.2;
  43.   si3 = 493.9;
  44.   do3 =  523.3;
  45.   do3_d = 554.4;
  46.   re3 = 587.3;
  47.   re3_d = 622.3;
  48.   mi3 = 659.3;
  49.   fa3  = 698.5;
  50.   fa3_d = 740.0;
  51.   sol3 = 784.0;
  52.   sol3_d = 830.6;
  53.   la4 = 880.0;
  54.   la4_d = 932.4;
  55.   si4 = 987.8;
  56.   do4 =  1046.6;
  57.   do4_d = 1108.8;
  58.   re4 = 1174.6;
  59.   re4_d = 1244.6;
  60.   mi4 = 1318.6;
  61.   fa4  = 1397.0;
  62.   fa4_d = 1480.0;
  63.   sol4 = 1568.0;
  64.   sol4_d = 1661.2;
  65.   la5 = 1760.0;
  66.  
  67.   // German music note
  68.   // A, B, C, D, E, F, G
  69.   a0  = 55.0;
  70.   a0_s = 58.3;
  71.   b0 = 61.7;
  72.   c0 =  65.4;
  73.   c0_s = 69.3;
  74.   d0 = 73.4;
  75.   d0_s = 77.8;
  76.   e0  = 82.4;
  77.   f0  = 87.3;
  78.   f0_s = 92.5;
  79.   g0 = 98.0;
  80.   g0_s = 103.8;
  81.   a1  = 110.0;
  82.   a1_s = 116.5;
  83.   b1 = 123.5;
  84.   c1 =  130.8;
  85.   c1_s = 138.6;
  86.   d1 = 146.8;
  87.   d1_s = 155.6;
  88.   e1  = 164.8;
  89.   f1  = 174.6;
  90.   f1_s = 185.0;
  91.   g1 = 196.0;
  92.   g1_s = 207.7;
  93.   a2 = 220.0;
  94.   a2_s = 233.1;
  95.   b2 = 2246.9;
  96.   c2 =  261.6;
  97.   c2_s = 277.2;
  98.   d2 = 293.7;
  99.   d2_s = 311.1;
  100.   e2  = 329.6;
  101.   f2  = 349.2;
  102.   f2_s = 370.0;
  103.   g2 = 392.0;
  104.   g2_s = 415.3;
  105.   a3  = 440.0;
  106.   a3_s = 466.2;
  107.   b3 = 493.9;
  108.   c3 =  523.3;
  109.   c3_s = 554.4;
  110.   d3 = 587.3;
  111.   d3_s = 622.3;
  112.   e3 = 659.3;
  113.   f3  = 698.5;
  114.   f3_s = 740.0;
  115.   g3 = 784.0;
  116.   g3_s = 830.6;
  117.   a4 = 880.0;
  118.   a4_s = 932.4;
  119.   b4 = 987.8;
  120.   c4 =  1046.6;
  121.   c4_s = 1108.8;
  122.   d4 = 1174.6;
  123.   d4_s = 1244.6;
  124.   e4 = 1318.6;
  125.   f4  = 1397.0;
  126.   f4_s = 1480.0;
  127.   g4 = 1568.0;
  128.   g4_s = 1661.2;
  129.   a5 = 1760.0;
« Last Edit: January 02, 2025, 02:16:13 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #2 on: January 02, 2025, 02:14:09 am »
Re-hello.

Maybe you will need also a sleep(duration_of_beep);
Like this (sorry I dont have Windows to test):

Code: Pascal  [Select][+][-]
  1.     procedure TForm1.DoReMiClick(Sender: TObject);
  2.     begin
  3.       FrequencyLabel.Caption := 'Do';
  4.       BeepAtFrequency(261);
  5.       application.processmessages;
  6.       Sleep(500);
  7.      
  8.       FrequencyLabel.Caption := 'Re';
  9.       BeepAtFrequency(293);
  10.       application.processmessages;
  11.       Sleep(500);
  12.      
  13.       FrequencyLabel.Caption := 'Mi';
  14.       BeepAtFrequency(329);
  15.       application.processmessages;
  16.       Sleep(500);
  17.      
  18.       FrequencyLabel.Caption := 'Fa';
  19.       BeepAtFrequency(349);
  20.       application.processmessages;
  21.       Sleep(500);
  22.     end;
« Last Edit: January 02, 2025, 06:06:42 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

OC DelGuy

  • Full Member
  • ***
  • Posts: 218
  • 123
Re: Pascal and Musical Tones :D
« Reply #3 on: January 03, 2025, 07:02:41 am »
Thanks I'll put those two lines in.  I had already thought about using Delay() to match the tempo of the beeps with a song, but I stopped because I was having the missing beep problem.  And the Delay()'s would go exactly where you put the sleeps.

All those extra notes!  I'm not musically inclined.  I'm just writing a short program that generates the tones like in the Rodgers and Hammerstein musical "The Sound of Music".  I might include other little tunes by writing a few more button events, but my knowledge of music is very lacking.  Later on I might add graphic piano keys and TShapes to make a keyboard.  Those notes will come in handy then!  :) 8-)

Oh, full disclosure, I got the 13 frequencies (in OP) from ChatGPT too.
Free Pascal Lazarus Version #: 2.2.4
Date: 24 SEP 2022
FPC Version: 3.2.2
Revision: Lazarus_2_2_4
x86_64-win64-win32/win64

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #4 on: January 03, 2025, 03:30:09 pm »
Later on I might add graphic piano keys and TShapes to make a keyboard.  Those notes will come in handy then!  :) 8-)

You may take inspiration from this project (it uses MSEgui pure Pascal widgetset).  ;)
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Pascal and Musical Tones :D
« Reply #5 on: January 03, 2025, 07:50:55 pm »
You can simply use 1.05946 as a const to resolve between notes. Everybody does that: it is the equal tempered 12 note scale. Which happens to be the 12th root of two.
But indeed, you can use a lookup table from, say, C-4 upto C+4 to prevent calculations.
(mimicing 144 key grand piano)
« Last Edit: January 03, 2025, 07:59:04 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Bart

  • Hero Member
  • *****
  • Posts: 5675
    • Bart en Mariska's Webstek
Re: Pascal and Musical Tones :D
« Reply #6 on: January 03, 2025, 08:12:40 pm »
Reminds me of an old "piano" program I once wrote using TP 6.0 and it's graph unit.
It supported glissando/staccato (yeah, right) and you could save/read in a simple format.
Maybe I even have the code somewhere on a floppy disk (not that I have a floppy drive anymore...).

@Thaddy: it used 12th root of 2 (as a constant, used my calculator for that) for the calculations.

Those were the days...

Bart

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Pascal and Musical Tones :D
« Reply #7 on: January 03, 2025, 09:19:19 pm »
I do not have the code anymore, but my program is still downloadable from:
https://www.softpedia.com/get/Multimedia/Audio/Other-AUDIO-Tools/Chord-Finder.shtml

I wrote that as a birthday present for a very good friend. She is a star singer/songwriter.

(Btw: If I find the code, it also has a piano keyboard control and midi support, see screenshots)

Rather flattered it is still available  :D
« Last Edit: January 03, 2025, 10:05:04 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #8 on: January 04, 2025, 04:48:41 pm »
I do not have the code anymore, but my program is still downloadable from:
https://www.softpedia.com/get/Multimedia/Audio/Other-AUDIO-Tools/Chord-Finder.shtml

Hello Thaddy.

Looks nice!

But the link for download gives this (see screen-shot).

 :-\
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #9 on: January 04, 2025, 05:37:13 pm »
I got this little bit of code from Chat GPT and it works fine.

It helped me to understand the Thaddy/Bart trick of 12th root of 2  :-X :

Q: Write a Pascal program to calculate piano note in hertz using root 12 of 2.

A:
Code: Pascal  [Select][+][-]
  1. program PianoNoteFrequency;
  2. var
  3.   root12of2, baseFrequency, noteFrequency: real;
  4.   semitoneOffset: integer;
  5. begin
  6.   { Calculate the 12th root of 2 }
  7.   root12of2 := exp(ln(2) / 12);
  8.  
  9.   { Set the base frequency of A4 (440 Hz) }
  10.   baseFrequency := 440.0;
  11.  
  12.   { Input the number of semitones from A4 }
  13.   writeln('Enter the number of semitones from A4 (positive for higher notes, negative for lower notes): ');
  14.   readln(semitoneOffset);
  15.  
  16.   { Calculate the frequency of the note }
  17.   noteFrequency := baseFrequency * exp(ln(root12of2) * semitoneOffset);
  18.  
  19.   { Output the result }
  20.   writeln('The frequency of the note is: ', noteFrequency:0:2, ' Hz');
  21. end.


Quote
Key Points:

    root12of2 stores the value of the 12th root of 2, calculated using exp(ln(2) / 12).
    baseFrequency is the reference frequency, which is 440 Hz for A4.
    semitoneOffset is the number of semitones the note is away from A4. A positive value is for higher notes, and a negative value is for lower notes.
    The frequency of the note is calculated as f(n)=f0×(2n12)f(n)=f0​×(212n​), or equivalently, f(n)=baseFrequency×root12of2semitoneOffsetf(n)=baseFrequency×root12of2semitoneOffset.

Example:

    If you input 0, the output will be 440.00 Hz (which is A4).
    If you input -9, the output will be 261.63 Hz (which is C4, 9 semitones below A4).

This program can calculate the frequency of any piano note by specifying how many semitones it is away from A4.

[EDIT]

Q: Ok, now write a Pascal program that calculates the frequency by note name, like A2, A3#, C4b, ...

A:
Code: Pascal  [Select][+][-]
  1. program PianoNoteByName;
  2.  
  3. uses sysutils;
  4. var
  5.   root12of2, baseFrequency, noteFrequency: real;
  6.   noteName: string;
  7.   semitoneOffset, octave: integer;
  8.  
  9. { Function to convert note name (with optional sharp or flat) to semitone offset from A4 }
  10. function GetSemitoneOffset(note: string; octave: integer): integer;
  11. var
  12.   notePart: string;
  13.   accidental: char;
  14.   noteBaseOffset: integer;
  15.   hasAccidental: boolean;
  16. begin
  17.   hasAccidental := false;
  18.  
  19.   { Check if the last character is a sharp (#) or flat (b) }
  20.   accidental := note[length(note)];
  21.   if (accidental = '#') or (accidental = 'b') then
  22.   begin
  23.     hasAccidental := true;
  24.     notePart := copy(note, 1, length(note) - 1);  { All but the last character (for Bb or A#) }
  25.   end
  26.   else
  27.   begin
  28.     notePart := note;  { The entire note (without accidental) }
  29.   end;
  30.  
  31.   { Base semitone offsets relative to A4 (using C0 as reference) }
  32.   if notePart = 'C' then
  33.     noteBaseOffset := -9  { C is 9 semitones below A in the same octave }
  34.   else if notePart = 'D' then
  35.     noteBaseOffset := -7
  36.   else if notePart = 'E' then
  37.     noteBaseOffset := -5
  38.   else if notePart = 'F' then
  39.     noteBaseOffset := -4
  40.   else if notePart = 'G' then
  41.     noteBaseOffset := -2
  42.   else if notePart = 'A' then
  43.     noteBaseOffset := 0
  44.   else if notePart = 'B' then
  45.     noteBaseOffset := 2
  46.   else
  47.   begin
  48.     writeln('Error: Invalid note name!');
  49.     halt;
  50.   end;
  51.  
  52.   { Adjust for accidentals (sharp '#' or flat 'b') if applicable }
  53.   if hasAccidental then
  54.   begin
  55.     if accidental = 'b' then
  56.       noteBaseOffset := noteBaseOffset - 1  { Flat lowers by 1 semitone }
  57.     else if accidental = '#' then
  58.       noteBaseOffset := noteBaseOffset + 1; { Sharp raises by 1 semitone }
  59.   end;
  60.  
  61.   { Calculate total semitone offset relative to A4 }
  62.   GetSemitoneOffset := noteBaseOffset + (octave - 4) * 12;
  63. end;
  64.  
  65. begin
  66.   { Calculate the 12th root of 2 }
  67.   root12of2 := exp(ln(2) / 12);
  68.  
  69.   { Set the base frequency of A4 (440 Hz) }
  70.   baseFrequency := 440.0;
  71.  
  72.   { Input the note name (e.g., C4, A3, Bb3, A#3) }
  73.   writeln('Enter the note (e.g., C4, A3, Bb3, A#3): ');
  74.   readln(noteName);
  75.  
  76.   { Extract the octave from the input (the last character) }
  77.   octave := StrToInt(noteName[length(noteName)]);  { Last character is the octave number }
  78.  
  79.   { Calculate the semitone offset from A4, based on the note name and octave }
  80.   semitoneOffset := GetSemitoneOffset(copy(noteName, 1, length(noteName) - 1), octave);
  81.  
  82.   { Calculate the frequency of the note using the semitone offset }
  83.   noteFrequency := baseFrequency * exp(ln(root12of2) * semitoneOffset);
  84.  
  85.   { Output the result }
  86.   writeln('The frequency of ', noteName, ' is: ', noteFrequency:0:2, ' Hz');
  87. end.
  88.  
Quote
How It Works:

    Input:
        You can input note names like C4, A3, Bb3 (B-flat 3), or A#3 (A-sharp 3).

    Processing:
        The function GetSemitoneOffset computes the semitone offset based on the note's name and octave.
        It supports flats (b) and sharps (#) by adjusting the semitone offset accordingly.

    Calculation:
        The semitone offset is then used to calculate the note's frequency based on the reference frequency of A4 = 440 Hz.
        The formula used is f(n)=f0×(2n12)f(n)=f0​×(212n​), which is implemented using the exp(ln(root12of2) * semitoneOffset).

    Output:        The frequency of the note is displayed in Hertz (Hz), rounded to 2 decimal places.

Example Inputs and Outputs:

    Input: C4
        Output: The frequency of C4 is: 261.63 Hz

    Input: A3
        Output: The frequency of A3 is: 220.00 Hz

    Input: Bb3
        Output: The frequency of Bb3 is: 233.08 Hz

    Input: A#3
        Output: The frequency of A#3 is: 233.08 Hz (same as Bb3, as they are enharmonic equivalents)

Key Features:

    Supports both sharps (#) and flats (b) in the note name.
    Calculates frequencies for notes across different octaves.
    Handles octave numbers properly and calculates semitone offsets from A4 (440 Hz).

This program will be user-friendly for musicians who are familiar with both flat and sharp notation and want to calculate the frequency of any note in the equal temperament scale.
Wow.  ;)
« Last Edit: January 04, 2025, 06:31:42 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Pascal and Musical Tones :D
« Reply #10 on: January 04, 2025, 09:17:14 pm »
But the link for download gives this (see screen-shot).
 :-\
Maybe I still have it, but need to search some disconnected hard disks. Or maybe it is still on one of mywebservers but out of sight.
Have to check. I know for sure it is still in the wild somewhere.

BTW, you should really do what Bart and I both suggested: It is a constant distance.
So creating a table of 12X12 of singles and precalculate the exp(ln(root12of2) for the matrix will speed up your code considerably since then it becomes a lookup instead of the expensive exp/ln. I would not use the constant I gave you for the lookup table, but calculate the table with the formula for higher precision - it is only once -, although over the range it does not matter much. A lookup also saves many clock cycles that can be used for audio processing.
And a 144 note range should be plenty.
« Last Edit: January 04, 2025, 09:33:02 pm by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #11 on: January 05, 2025, 03:49:06 am »
For the fun, this project release to show frequencies of notes.
In both notation (german: A2, C#3, Gb1...) or latin solfege (do3, re2, mi#4, ...).
It uses the 12th root of 2 trick and MSEgui widgetset.

[EDIT] Added conversion of frequency to nearest piano note.

[EDIT2]
Quote
So creating a table of 12X12 of singles and precalculate the exp(ln(root12of2) for the matrix
OK, this work:
Code: Pascal  [Select][+][-]
  1. const
  2.   NumNotes = 12;  { Number of semitones per octave }
  3.   A4Frequency = 440.0;  { Reference frequency for A4 (440 Hz) }
  4.   A4Index = 9;  { A4 is the 10th note in the scale (0-indexed), hence position 9 in the octave }
  5.   A4Octave = 4;  { A4 is in the 4th octave (C0 starts at octave 0) }
  6.  
  7. var
  8.   frequencies: array[1..NumNotes, 1..NumNotes] of real;  { 12x12 array for frequencies }
  9.   i, j, n: integer;  { Loop variables }
  10.   powerFactor: real;
  11.  
  12. begin
  13.    { Calculate and fill the frequencies array }
  14.   for i := 0 to NumNotes-1 do   { i = octave }
  15.     for j := 0 to NumNotes-1 do  { j = note in the octave }
  16.     begin
  17.       { Calculate the number of semitone steps away from A4 (A4 = 440 Hz at octave 4) }
  18.       n := (i * NumNotes + j) - (A4Octave * NumNotes + A4Index);
  19.       powerFactor := n / 12.0;
  20.       frequencies[i+1, j+1] := A4Frequency * exp(powerFactor * ln(2));  { Calculate frequency using exp and ln }
  21.     end;
  22. end;
« Last Edit: January 05, 2025, 08:59:09 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Thaddy

  • Hero Member
  • *****
  • Posts: 18729
  • To Europe: simply sell USA bonds: dollar collapses
Re: Pascal and Musical Tones :D
« Reply #12 on: January 05, 2025, 09:47:47 am »
Fred, while searching for the chordfinder code, that I did not fid yet,I found something that may be of interest to you. A 32 bit audio manipulation library I wrote in 2004. Written in 8087 assembly and some mmx.
At the time I did all audio processing in the floating point domain before passing the audio to ASIO buffers in the correct format. Should also work with Alsa or Jack buffers.

Well documented. Win/Lin. Attached.
« Last Edit: January 05, 2025, 10:08:28 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

Fred vS

  • Hero Member
  • *****
  • Posts: 3780
    • StrumPract is the musicians best friend
Re: Pascal and Musical Tones :D
« Reply #13 on: January 05, 2025, 09:21:30 pm »
Fred, while searching for the chordfinder code, that I did not fid yet,I found something that may be of interest to you. A 32 bit audio manipulation library I wrote in 2004. Written in 8087 assembly and some mmx.
At the time I did all audio processing in the floating point domain before passing the audio to ASIO buffers in the correct format. Should also work with Alsa or Jack buffers.

Well documented. Win/Lin. Attached.

Hello Thaddy.

Wow, great project.
I dont use Windows anymore (nor Jack) but sure I can find some interesting things.
Many thanks and have a perfect year.

Fre;D
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Boleeman

  • Hero Member
  • *****
  • Posts: 1108
Re: Pascal and Musical Tones :D
« Reply #14 on: January 06, 2025, 10:26:19 am »
Accidentally came across some interesting sound/tone JavaScript programs here while looking for something else:

https://github.com/aatishb/stringmath
https://github.com/aatishb/springtuning
https://github.com/aatishb/preparedpianosynth
https://github.com/aatishb/differencetones
https://github.com/aatishb/sound-microscope

Might be useful to get some ideas for a Lazarus sound/tone explorer.

 

TinyPortal © 2005-2018