Ottenere la frequenza corrispondente ad una nota Midi e viceversa

Da Gambas-it.org - Wikipedia.

Ottenere la frequenza corrispondente ad una nota Midi

Come è noto, nel Midi le note sono numerate da 0 a 127.

Per ottenere la frequenza corrispondente ad una nota Midi e viceversa, sono possibili almeno quattro modalità.

Uso delle sole funzioni di Gambas

Il calcolo della frequenza può essere effettuato mediante almeno due modalità.

In entrambe le possibilità poniamo il caso di voler trovare la frequenza sonora, alla quale corrisponde la nota Midi num. 69 (LA).

1a modalità

Public Sub Main()

 Dim frequenza As Single
 Dim nota_Midi As Byte
 
' Otteniamo per esempio il numero della nota Midi corrispondente al La (hz 440) corrispondente numero 69:
 nota_Midi = 69

' La frequenza di riferimento è quella del Do dell'ottava n. 0, nota Midi n. 12, (hz 16.3516):
 frequenza = 16.3516 * (2 ^ (1 / 12)) ^ (nota_Midi - 12)

 Print "Frequenza = "; frequenza; " Hertz"

End


2a modalità

Private Const M_LN2l As Float = 0.69314718055995


Public Sub Main()

 Dim nota_midi, freq As Single

 nota_midi = 69
     
 freq = Exp(((nota_midi + 3.0) / 12.0) * M_LN2l) * 6.875
      
 Print "La nota Midi "; nota_midi; " = "; freq; " hertz"
 
End

4a modalità

Public Sub Main()

 Dim freq As Float
 Dim nota_midi As Integer

 nota_midi = 69
     
 freq = Exp(Log(440.0) + CFloat(midi - 69) * Log(2.0) / 12.0)
      
 Print "La nota Midi "; nota_midi; " = "; freq; " hertz"
 
End

Ottenere una lista delle note musicali e relative ottave e frequenze di una tastiera musicale da 88 tasti

Private Const NUM_NOTE As Byte = 88


Public Sub Main()
 
 Dim nome As String[] = ["DO", "DO#", "RE", "RE#", "MI", "FA", "FA#", "SOL", "SOL#", "LA", "LA#", "SI"]
 Dim b As Byte

 Print "NOTA  OTTAVA   FREQUENZA"
 For b = 0 To NUM_NOTE - 1
    Print NomeNote(nome, b), Ottave(b), Frequenza(b + 1); " hertz"
 Next

End


Private Function NomeNote(nomen As String[], n As Byte) As String
 
 Return nomen[((n) + 9) Mod 12]
 
End


Private Function Ottave(n As Byte) As Byte

 Return (((n) + 9) / 12)

End


Private Function Frequenza(n As Byte) As Short

 Return CShort((2 ^ (1.0 / 12.0)) ^ (n - 49.0) * 440.0 + 0.5)

End


Uso dell'API di Libaubio

La libreria Libaubio consente, fra l'altro, di convertire una nota Midi nella corrispondente frequenza sonora.

Per poter fruire in Gambas delle risorse della libreria Libaubio, è necessario installare nel sistema e richiamare in Gambas la libreria dinamica condivisa: "libaubio:4.0.0"

Mostriamo un esempio pratico:

Library "libaubio:4.0.0"
 
' smpl_t aubio_miditofreq (smpl_t midi)
' Convert midi value (0-128) to frequency (Hz).
Private Extern aubio_miditofreq(midi As Single) As Single


Public Sub Main()
 
 Dim freq, mid As Single

 mid = 69

 freq = aubio_miditofreq(mid)
 Print "\n\nNota Midi     "; mid; "\nFrequenza: hz "; freq
 
End


Ottenere la nota Midi corrispondente ad una frequenza sonora

Per ottenere la nota Midi corrispondente ad una la frequenza sonora, sono possibili almeno quattro modalità.

Uso delle sole funzioni di Gambas

Il calcolo del numero della nota Midi mediante le sole risorse di Gambas può essere effettuato mediante almeno due modalità.

1a modalità

Public Sub Main()

 Dim freq, nota As Float

 freq = 440.00
 nota = Log(((freq / 261.63) ^ 12) * (2 ^ 60)) / Log(2)
  
 Print Round(nota)

End

2a modalità

Private Const M_LN2l As Float = 0.69314718055995


Public Sub Main()
 
 Dim nota_midi, freq As Single

 freq = 440.0
  
 nota_midi = ((Log(freq / 6.875) / M_LN2l) * 12) - 3
 
 Print "La frequenza Hz "; freq; " = nota Midi "; nota_midi
   
End

3a modalità

Public Sub Main()
 
 Dim freq As Float
 Dim nota_midi As Byte

 freq = 440.0
  
 nota_midi = CByte((0.5 + 69.0 + 12.0 / Log(2.0) * Log(f / 440.0)))
 
 Print "La frequenza Hz "; freq; " = nota Midi "; nota_midi
   
End

Uso dell'API di Libaubio

Mostriamo un esempio pratico con l'API della libreria Libaubio:

Library "libaubio:4.0.0"
 
' smpl_t aubio_freqtomidi (smpl_t freq)
' Convert frequency (Hz) to midi value (0-128).
Private Extern aubio_freqtomidi(freq As Single) As Single


Public Sub Main()
 
 Dim frequenza, mid As Single
 
 frequenza = 440.0

 mid = aubio_freqtomidi(frequenza)
 Print "Frequenza: hz "; frequenza; "\nNota Midi     "; mid
  
End


Numero delle note MIDI e corrispondente Frequenza in Hertz

   MIDI                 MIDI                   MIDI
   Nota   Frequency     Nota   Frequency       Nota   Frequency
C  0    8.1757989156    12    16.3515978313    24    32.7031956626
Db 1    8.6619572180    13    17.3239144361    25    34.6478288721
D  2    9.1770239974    14    18.3540479948    26    36.7080959897
Eb 3    9.7227182413    15    19.4454364826    27    38.8908729653
E  4   10.3008611535    16    20.6017223071    28    41.2034446141
F  5   10.9133822323    17    21.8267644646    29    43.6535289291
Gb 6   11.5623257097    18    23.1246514195    30    46.2493028390
G  7   12.2498573744    19    24.4997147489    31    48.9994294977
Ab 8   12.9782717994    20    25.9565435987    32    51.9130871975
A  9   13.7500000000    21    27.5000000000    33    55.0000000000
Bb 10  14.5676175474    22    29.1352350949    34    58.2704701898
B  11  15.4338531643    23    30.8677063285    35    61.7354126570

C  36  65.4063913251    48   130.8127826503    60   261.6255653006
Db 37  69.2956577442    49   138.5913154884    61   277.1826309769
D  38  73.4161919794    50   146.8323839587    62   293.6647679174
Eb 39  77.7817459305    51   155.5634918610    63   311.1269837221
E  40  82.4068892282    52   164.8137784564    64   329.6275569129
F  41  87.3070578583    53   174.6141157165    65   349.2282314330
Gb 42  92.4986056779    54   184.9972113558    66   369.9944227116
G  43  97.9988589954    55   195.9977179909    67   391.9954359817
Ab 44  103.8261743950   56   207.6523487900    68   415.3046975799
A  45  110.0000000000   57   220.0000000000    69   440.0000000000
Bb 46  116.5409403795   58   233.0818807590    70   466.1637615181
B  47  123.4708253140   59   246.9416506281    71   493.8833012561

C  72  523.2511306012   84  1046.5022612024    96  2093.0045224048
Db 73  554.3652619537   85  1108.7305239075    97  2217.4610478150
D  74  587.3295358348   86  1174.6590716696    98  2349.3181433393
Eb 75  622.2539674442   87  1244.5079348883    99  2489.0158697766
E  76  659.2551138257   88  1318.5102276515   100  2637.0204553030
F  77  698.4564628660   89  1396.9129257320   101  2793.8258514640
Gb 78  739.9888454233   90  1479.9776908465   102  2959.9553816931
G  79  783.9908719635   91  1567.9817439270   103  3135.9634878540
Ab 80  830.6093951599   92  1661.2187903198   104  3322.4375806396
A  81  880.0000000000   93  1760.0000000000   105  3520.0000000000
Bb 82  932.3275230362   94  1864.6550460724   106  3729.3100921447
B  83  987.7666025122   95  1975.5332050245   107  3951.0664100490

C  108 4186.0090448096  120  8372.0180896192
Db 109 4434.9220956300  121  8869.8441912599
D  110 4698.6362866785  122  9397.2725733570
Eb 111 4978.0317395533  123  9956.0634791066
E  112 5274.0409106059  124 10548.0818212118
F  113 5587.6517029281  125 11175.3034058561
Gb 114 5919.9107633862  126 11839.8215267723
G  115 6271.9269757080  127 12543.8539514160
Ab 116 6644.8751612791
A  117 7040.0000000000
Bb 118 7458.6201842894
B  119 7902.1328200980

Nota: il Do centrale corrisponde alla nota midi num. 60.

Here's a BASIC program to calculate an array with all of the above frequencies (ie, so that MIDI(0), which pertains to note #0, is assigned the value of 8.1757989156). Tuning is based upon A=440.

<FONT COLOR=BLUE>DIM</FONT> MIDI(127)
A=440
<FONT COLOR=BLUE>FOR</FONT> x = 0 to 127
MIDI(x) = (A / 32) * (2 ^ ((x - 9) / 12))
<FONT COLOR=BLUE>NEXT</FONT> x

If you plan to always use 440 tuning, then you can use this simplified code instead:

<FONT COLOR=BLUE>DIM</FONT> MIDI(127)
<FONT COLOR=BLUE>FOR</FONT> x = 0 to 127
MIDI(x) = 8.1758 * 2^(x/12)
<FONT COLOR=BLUE>NEXT</FONT> x



Riferimenti