Generare un'onda sinusoidale con le sole funzioni di Gambas
Da Gambas-it.org - Wikipedia.
Versione del 22 gen 2015 alle 08:45 di Vuott (Discussione | contributi)
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(dg As File) Dim intes 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: intes = Open "/tmp/blocco_header" For Create bb.Write(intes, 0, 4) Write #intes, Lof(dg) + 36 As Integer bb.Write(intes, 8, 32) Write #intes, Lof(dg) As Integer intes.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