Option Explicit
Declare Function Beep Lib "kernel32.dll" _
(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
'
Sub Essai()
Dim N As Long, DegDép&, Deg&, Dxx&, Maj&, Dur&
For N = 1 To 700
Deg = Array(0, 3 + Maj, 7, 12)(Int(4 * Rnd)) + DegDép
Dur = 125 * 2 ^ Int(Rnd * 3)
Beep Int(FréqDegr(Deg) + 0.5), Dur
If Rnd > 0.75 Then
Maj = 1 - Int(Rnd * 1.5)
Dxx = Array(0, 3 + Maj, 7, 12)(Int(4 * Rnd))
DegDép = Deg - Dxx
If DegDép < -24 Then DegDép = DegDép + 12 Else _
If DegDép > 24 Then DegDép = DegDép - 12
End If
Next N
End Sub
'
Function NoteDeg(ByVal Degr As Long) As String
Dim Résu As String, Octa As Long
DegréNO(Résu, Octa) = Degr
Résu = Left$(Résu & " ", 2)
If Octa > 0 Then Résu = Résu & "+" & Octa & "o" Else If Octa < 0 Then Résu = Résu & Octa & "o"
NoteDeg = Résu
End Function
Function DegNote(ByVal Note As String, Optional ByVal Octa As Long = 0) As Long
DegNote = DegréNO(Note, Octa)
End Function
Function NoteFréq(ByVal Fréq As Double) As String
If Fréq = 0 Then NoteFréq = "" Else NoteFréq = NoteDeg(DegrFréq(Fréq))
End Function
Function FréqNote(ByVal Note As String, Optional ByVal Octa As Long = 0) As Double
FréqNote = FréqDegr(DegréNO(Note, Octa))
End Function
'
Property Get DegréNO(Note As String, Optional Octa As Long = 0) As Long
DegréNO = InStr("A BC D EF G", UCase(Left$(Note, 1))) + (InStr("#b ", Mid$(Note & " ", 2, 1)) + 1) Mod 3 - 2 + 12 * Octa
End Property
Property Let DegréNO(Note As String, Optional Octa As Long, ByVal Degr As Long)
Octa = (Degr + 1200) \ 12 - 100: Degr = Degr - 12 * Octa
Note = Mid$(" A#BC#D#EF#G#", Degr + 1, 2): If Right$(Note, 1) <> "#" Then Note = Right$(Note, 1)
End Property
'
Function FréqDegr(Degr As Long) As Double
FréqDegr = 440 * 2 ^ (Degr / 12) '= 1,0594630943592952645618252949463^Note
End Function
Function DegrFréq(Fréq As Double) As Long
Const k12÷Ln2 = 212857425 / 12295127 '17,312340490667560888319096172023
DegrFréq = Round(Log(Fréq / 440) * k12÷Ln2)
End Function