Generare un'onda sinusoidale con le sole funzioni di Gambas
Vai alla navigazione
Vai alla ricerca
E' possibile generare un'onda sinusoidale con le sole risorse di Gambas.
Mostriamo un esempio (tratto da analogo codice scritto in C da Fabrice Bellard e convertito qui in Gambas con modifiche ed integrazioni), al termine del quale verrà creato un file di tipo WAV contenente i dati audio e che consentirà di eseguire l'onda sinusoidale campionata:
Private Const RISOL_BIT As Integer = 16
Private Const COST_TAB_VAL As Integer = 7
Private FRAZIONE As Integer = 1 * CInt(2 ^ RISOL_BIT)
Private CSHIFT As Integer = RISOL_BIT - COST_TAB_VAL - 2
Private Tabella_Valori As Integer[] = [&8000&, &7ffe, &7ff6, &7fea, &7fd9, &7fc2, &7fa7, &7f87,
&7f62, &7f38, &7f0a, &7ed6, &7e9d, &7e60, &7e1e, &7dd6,
&7d8a, &7d3a, &7ce4, &7c89, &7c2a, &7bc6, &7b5d, &7aef,
&7a7d, &7a06, &798a, &790a, &7885, &77fb, &776c, &76d9,
&7642, &75a6, &7505, &7460, &73b6, &7308, &7255, &719e,
&70e3, &7023, &6f5f, &6e97, &6dca, &6cf9, &6c24, &6b4b,
&6a6e, &698c, &68a7, &67bd, &66d0, &65de, &64e9, &63ef,
&62f2, &61f1, &60ec, &5fe4, &5ed7, &5dc8, &5cb4, &5b9d,
&5a82, &5964, &5843, &571e, &55f6, &54ca, &539b, &5269,
&5134, &4ffb, &4ec0, &4d81, &4c40, &4afb, &49b4, &486a,
&471d, &45cd, &447b, &4326, &41ce, &4074, &3f17, &3db8,
&3c57, &3af3, &398d, &3825, &36ba, &354e, &33df, &326e,
&30fc, &2f87, &2e11, &2c99, &2b1f, &29a4, &2827, &26a8,
&2528, &23a7, &2224, &209f, &1f1a, &1d93, &1c0c, &1a83,
&18f9, &176e, &15e2, &1455, &12c8, &113a, &0fab, &0e1c,
&0c8c, &0afb, &096b, &07d9, &0648, &04b6, &0324, &0192,
&0000, &0000]
Public Sub Main()
Dim fl As File
Dim filegrezzo As String
Dim i, a, v, j As Integer
Dim campionamento, canali, frequenza, volume As Integer
Dim durata As Single
filegrezzo = "/tmp/datigrezzi" ' File contenente i dati audio grezzi dell'onda
campionamento = 44100 ' Frequenza di campionamento dell'onda
canali = 2 ' Numero canali del file WAV
frequenza = 440 ' Frequenza dell'onda
durata = 3.0 ' Durata in secondi
volume = 10000 ' Volume audio dell'onda
fl = Open filegrezzo For Create
If IsNull(fl) Then Error.Raise("Impossibile creare il file dei dati audio grezzi !")
' Genera 3 secondi di un'onda sinusoidale alla frequenza di Hz 440:
For i = 0 To (durata * campionamento) - 1
v = (int_cos(a) * volume) \ CInt(2 ^ RISOL_BIT)
For j = 0 To canali - 1
Scrivi_File(fl, v)
Next
a += (frequenza * FRAZIONE) / campionamento
Next
Crea_File_WAV(fl)
fl.Close
Print "Fine creazione dell'onda."
End
Private Function Int_Cos(a As Integer) As Integer
Dim neg, v, f As Integer
Dim p As Integer[]
a = a And (FRAZIONE - 1)
If a >= (FRAZIONE / 2) Then a = FRAZIONE - a
neg = 0
If a > (FRAZIONE / 4) Then
neg = -1
a = (FRAZIONE / 2) - a
Endif
p = Tabella_Valori.Copy(a \ CInt(2 ^ CSHIFT), Tabella_Valori.Count - a \ CInt(2 ^ CSHIFT))
' Interpolazione lineare:
f = a And ((1 * CInt(2 ^ CSHIFT)) - 1)
v = p[0] + (((p[1] - p[0]) * f + (1 * CInt(2 ^ (CSHIFT - 1)))) / CInt(2 ^ CSHIFT))
v = (v Xor neg) - neg
v = v * CInt(2 ^ (RISOL_BIT - 15))
Return v
End
Private Procedure Scrivi_File(sf As File, v As Integer)
Write #sf, CByte(v And &ff) As Byte
Write #sf, CByte((v \ CInt(2 ^ 8)) And &ff) As Byte
End
Private Procedure Crea_File_WAV(cf As File)
Dim int As File
Dim bb As Byte[] = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56,
&45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00,
&02, &00, &44, &AC, &00, &00, &10, &B1, &02, &00, &04,
&00, &10, &00, &64, &61, &74, &61]
' Scrive innanzitutto il blocco di intestazione del file WAV:
int = Open "/tmp/blocco_header" For Create
bb.Write(int, 0, 4)
Write #int, Lof(dg) + 36 As Integer
bb.Write(int, 8, 32)
Write #int, Lof(dg) As Integer
int.Close
' Unisce il blocco di intestazione del file WAV ai dati audio grezzi presenti nel file "datigrezzi"
' (in questo esempio il file WAV finale viene scritto nella cartella "/tmp"):
File.Save("/tmp/onda.wav", File.Load("/tmp/blocco_header") & File.Load("/tmp/datigrezzi"))
End