Generare un'onda sinusoidale con il componente gb.openal: differenze tra le versioni
Vai alla navigazione
Vai alla ricerca
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (10 versioni intermedie di uno stesso utente non sono mostrate) | |||
| Riga 1: | Riga 1: | ||
Utilizzando le risorse della Classe | Utilizzando le risorse della Classe ''Alc'' del Componente ''gb.openal'' di Gambas, è possibile eseguire un'onda sinusoidale, i cui dati saranno realizzati mediante apposita formula matematica. | ||
Vediamo un esempio pratico: | Vediamo un esempio pratico: | ||
| Riga 8: | Riga 8: | ||
''' | Public Sub Main() | ||
Dim disp As AlcDevice | |||
Dim cont As AlcContext | |||
Dim src, buffer As Integer[] | |||
Dim err As Boolean | |||
Dim dati As New Byte[] | |||
<FONT Color=gray>' ''Configura il dispositivo audio con la Classe "Alc":''</font> | |||
disp = Alc.OpenDevice(Null) | |||
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !") | |||
<FONT Color=gray>' ''Configura il contesto audio con la Classe "Alc":''</font> | |||
cont = Alc.CreateContext(disp) | |||
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !") | |||
err = cont.MakeCurrent() | |||
If err = False Then Error.Raise("Impossibile creare il contesto audio !") | |||
src = Al.GenSources(1) | |||
If IsNull(src) Then Error.Raise("Errore !") | |||
<FONT Color=gray>' ''Configura il buffer audio:''</font> | |||
buffer = Al.GenBuffers(1) | |||
If IsNull(buffer) Then Error.Raise("Errore !") | |||
Onda(dati) | |||
<FONT Color=gray>' ''I dati audio sono caricati nel buffer audio:''</font> | |||
Al.BufferData(buffer[0], al.FORMAT_MONO8, dati.Data, dati.Count, CAMPIONAMENTO) | |||
<FONT Color=gray>' ''Connette il buffer audio al sorgente audio:''</font> | |||
Al.Sourcei(src[0], Al.BUFFER, buffer[0]) | |||
<FONT Color=gray>' ''Esegue il sorgente audio:''</font> | |||
Al.SourcePlay(src[0]) | |||
<FONT Color=gray>' ''Consente l'esecuzione per l'intera durata dell'onda sonora:''</font> | |||
Wait DURATA | |||
Al.SourceStop(src[0]) | |||
<FONT Color=gray>' ''Libera la memoria:''</font> | |||
Al.DeleteBuffers(buffer) | |||
Al.DeleteSources(src) | |||
Alc.DestroyContext(cont) | |||
Alc.CloseDevice(disp) | |||
End | |||
Private Function Onda(bb As Byte[]) <FONT Color=gray>' ''Crea i dati dell'onda sinusoidale''</font> | |||
Dim i As Integer | |||
For i = 0 To (DURATA * CAMPIONAMENTO) - 1 | |||
bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi))))) | |||
Next | |||
End | |||
In quest'altro codice, simile al precedente, applicheremo ai dati dell'onda sinusoidale l'effetto della ''[https://it.wikipedia.org/wiki/Funzione_finestra Funzione Finestra di Hamming]'': | |||
Private Const AMPIEZZA As Byte = 127 | |||
Private Const FREQUENZA As Short = 440 | |||
Private Const CAMPIONAMENTO As Integer = 44100 | |||
Private Const DURATA As Single = 20.0 | |||
Private Const AMP_HAMM As Single = 0.95 | |||
Private Const TEMPO_DISCRETO As Integer = 16384 | |||
Public Sub Main() | |||
Dim disp As AlcDevice | Dim disp As AlcDevice | ||
Dim cont As AlcContext | Dim cont As AlcContext | ||
Dim src, buffer As Integer[] | Dim src, buffer As Integer[] | ||
Dim err As Boolean | Dim err As Boolean | ||
Dim dati As New Byte[] | Dim dati As New Byte[] | ||
<FONT Color=gray>' ''Configura il dispositivo audio con la Classe "Alc":''</font> | <FONT Color=gray>' ''Configura il dispositivo audio con la Classe "Alc":''</font> | ||
disp = Alc.OpenDevice(Null) | |||
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !") | |||
<FONT Color=gray>' ''Configura il contesto audio con la Classe "Alc":''</font> | <FONT Color=gray>' ''Configura il contesto audio con la Classe "Alc":''</font> | ||
cont = Alc.CreateContext(disp) | |||
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !") | |||
err = cont.MakeCurrent() | |||
If err = False Then Error.Raise("Impossibile creare il contesto audio !") | |||
src = Al.GenSources(1) | |||
If IsNull(src) Then Error.Raise("Errore !") | |||
<FONT Color=gray>' ''Configura il buffer audio:''</font> | <FONT Color=gray>' ''Configura il buffer audio:''</font> | ||
buffer = Al.GenBuffers(1) | |||
If IsNull(buffer) Then Error.Raise("Errore !") | |||
Onda(dati) | |||
<FONT Color=gray>' ''I dati audio sono caricati nel buffer audio:''</font> | <FONT Color=gray>' ''I dati audio sono caricati nel buffer audio:''</font> | ||
Al.BufferData(buffer[0], al.FORMAT_MONO8, dati.Data, dati.Count, CAMPIONAMENTO) | |||
<FONT Color=gray>' ''Connette il buffer audio al sorgente audio:''</font> | <FONT Color=gray>' ''Connette il buffer audio al sorgente audio:''</font> | ||
Al.Sourcei(src[0], Al.BUFFER, buffer[0]) | |||
<FONT Color=gray>' ''Esegue il sorgente audio:''</font> | <FONT Color=gray>' ''Esegue il sorgente audio:''</font> | ||
Al.SourcePlay(src[0]) | |||
<FONT Color=gray>' ''Consente l'esecuzione per l'intera durata dell'onda sonora:''</font> | <FONT Color=gray>' ''Consente l'esecuzione per l'intera durata dell'onda sonora:''</font> | ||
Wait DURATA | |||
Al.SourceStop(src[0]) | |||
<FONT Color=gray>' ''Libera la memoria:''</font> | <FONT Color=gray>' ''Libera la memoria:''</font> | ||
Al.DeleteBuffers(buffer) | |||
Al.DeleteSources(src) | |||
Alc.DestroyContext(cont) | |||
Alc.CloseDevice(disp) | |||
End | |||
Private Function Onda(bb As Byte[]) <FONT Color=gray>' ''Crea i dati dell'onda sinusoidale''</font> | |||
Dim i As Integer | |||
'''End''' | For i = 0 To (DURATA * CAMPIONAMENTO) - 1 | ||
bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi))))) | |||
<FONT Color=gray>' ''Applica la Funzione Finestra di Hamming:''</font> | |||
bb[i] *= AMP_HAMM * (0.54 - 0.46 * Cos(2.0 * Pi * i / (TEMPO_DISCRETO - 1))) | |||
Next | |||
End | |||
In questo codice utilizzeremo un'altra formula per generare i dati dell'onda sinusoidale, i quali in questo caso avranno una definizione a 16-bit. Inoltre al termine dell'esecuzione audio dell'onda sinusoidale, i dati audio grezzi saranno salvati in un file. | |||
Private Const AMPIEZZA As Byte = 128 | |||
Private Const CAMPIONAMENTO As Integer = 44100 | |||
Private Const FREQUENZA As Short = 440 | |||
Private Const DURATA As Single = 10.0 | |||
Private Const AMP_HAMM As Single = 32.0 | |||
Private Const TEMPO_DISCRETO As Integer = 32768 | |||
Public Sub Main() | |||
Dim disp As AlcDevice | |||
Dim cont As AlcContext | |||
Dim src, buffer As Integer[] | |||
Dim err As Boolean | |||
Dim dati As New Short[] | |||
disp = Alc.OpenDevice(Null) | |||
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !") | |||
cont = Alc.CreateContext(disp) | |||
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !") | |||
err = cont.MakeCurrent() | |||
If err = False Then Error.Raise("Impossibile creare il contesto audio !") | |||
src = Al.GenSources(1) | |||
If IsNull(src) Then Error.Raise("Errore !") | |||
buffer = Al.GenBuffers(1) | |||
If IsNull(buffer) Then Error.Raise("Errore !") | |||
Onda(dati) | |||
Al.BufferData(buffer[0], al.FORMAT_MONO16, dati.Data, dati.Count, CAMPIONAMENTO) | |||
Al.Sourcei(src[0], Al.BUFFER, buffer[0]) | |||
Al.SourcePlay(src[0]) | |||
Wait DURATA | |||
Al.SourceStop(src[0]) | |||
<FONT Color=gray>' ''Libera la memoria:''</font> | |||
Al.DeleteBuffers(buffer) | |||
Al.DeleteSources(src) | |||
Alc.DestroyContext(cont) | |||
Alc.CloseDevice(disp) | |||
Dim | <FONT Color=gray>' ''Va a generare il file contenente i dati audio grezzi:''</font> | ||
CreaFileDatiGrezzi(dati) | |||
End | |||
Private Function Onda(data As Short[]) ' Crea i dati dell'onda sinusoidale | |||
Dim k As Integer | |||
For k = 0 To (DURATA * CAMPIONAMENTO) - 1 | |||
data.Push(AMPIEZZA * Sin(2.0 * k * Pi * 1.0 / 64.0 + 0.4)) | |||
<FONT Color=gray>' ''Applica la Funzione Finestra di Hamming:''</font> | |||
data[k] *= AMP_HAMM * (0.54 - 0.46 * Cos(2.0 * Pi * k / (TEMPO_DISCRETO - 1))) | |||
Next | |||
End | |||
Private Procedure CreaFileDatiGrezzi(grezzi As Short[]) | |||
Dim fl As File | |||
fl = Open "/tmp/dati_audio" For Create | |||
<FONT Color=gray>' ''Salva i dati audio grezzi nel file:''</font> | |||
grezzi.Write(fl, 0, grezzi.Count) | |||
fl.Close | |||
End | |||
Versione attuale delle 19:15, 5 ott 2024
Utilizzando le risorse della Classe Alc del Componente gb.openal di Gambas, è possibile eseguire un'onda sinusoidale, i cui dati saranno realizzati mediante apposita formula matematica.
Vediamo un esempio pratico:
Private Const AMPIEZZA As Byte = 127
Private Const FREQUENZA As Short = 880
Private Const CAMPIONAMENTO As Integer = 44100
Private Const DURATA As Single = 4.0
Public Sub Main()
Dim disp As AlcDevice
Dim cont As AlcContext
Dim src, buffer As Integer[]
Dim err As Boolean
Dim dati As New Byte[]
' Configura il dispositivo audio con la Classe "Alc":
disp = Alc.OpenDevice(Null)
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !")
' Configura il contesto audio con la Classe "Alc":
cont = Alc.CreateContext(disp)
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
err = cont.MakeCurrent()
If err = False Then Error.Raise("Impossibile creare il contesto audio !")
src = Al.GenSources(1)
If IsNull(src) Then Error.Raise("Errore !")
' Configura il buffer audio:
buffer = Al.GenBuffers(1)
If IsNull(buffer) Then Error.Raise("Errore !")
Onda(dati)
' I dati audio sono caricati nel buffer audio:
Al.BufferData(buffer[0], al.FORMAT_MONO8, dati.Data, dati.Count, CAMPIONAMENTO)
' Connette il buffer audio al sorgente audio:
Al.Sourcei(src[0], Al.BUFFER, buffer[0])
' Esegue il sorgente audio:
Al.SourcePlay(src[0])
' Consente l'esecuzione per l'intera durata dell'onda sonora:
Wait DURATA
Al.SourceStop(src[0])
' Libera la memoria:
Al.DeleteBuffers(buffer)
Al.DeleteSources(src)
Alc.DestroyContext(cont)
Alc.CloseDevice(disp)
End
Private Function Onda(bb As Byte[]) ' Crea i dati dell'onda sinusoidale
Dim i As Integer
For i = 0 To (DURATA * CAMPIONAMENTO) - 1
bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi)))))
Next
End
In quest'altro codice, simile al precedente, applicheremo ai dati dell'onda sinusoidale l'effetto della Funzione Finestra di Hamming:
Private Const AMPIEZZA As Byte = 127
Private Const FREQUENZA As Short = 440
Private Const CAMPIONAMENTO As Integer = 44100
Private Const DURATA As Single = 20.0
Private Const AMP_HAMM As Single = 0.95
Private Const TEMPO_DISCRETO As Integer = 16384
Public Sub Main()
Dim disp As AlcDevice
Dim cont As AlcContext
Dim src, buffer As Integer[]
Dim err As Boolean
Dim dati As New Byte[]
' Configura il dispositivo audio con la Classe "Alc":
disp = Alc.OpenDevice(Null)
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !")
' Configura il contesto audio con la Classe "Alc":
cont = Alc.CreateContext(disp)
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
err = cont.MakeCurrent()
If err = False Then Error.Raise("Impossibile creare il contesto audio !")
src = Al.GenSources(1)
If IsNull(src) Then Error.Raise("Errore !")
' Configura il buffer audio:
buffer = Al.GenBuffers(1)
If IsNull(buffer) Then Error.Raise("Errore !")
Onda(dati)
' I dati audio sono caricati nel buffer audio:
Al.BufferData(buffer[0], al.FORMAT_MONO8, dati.Data, dati.Count, CAMPIONAMENTO)
' Connette il buffer audio al sorgente audio:
Al.Sourcei(src[0], Al.BUFFER, buffer[0])
' Esegue il sorgente audio:
Al.SourcePlay(src[0])
' Consente l'esecuzione per l'intera durata dell'onda sonora:
Wait DURATA
Al.SourceStop(src[0])
' Libera la memoria:
Al.DeleteBuffers(buffer)
Al.DeleteSources(src)
Alc.DestroyContext(cont)
Alc.CloseDevice(disp)
End
Private Function Onda(bb As Byte[]) ' Crea i dati dell'onda sinusoidale
Dim i As Integer
For i = 0 To (DURATA * CAMPIONAMENTO) - 1
bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi)))))
' Applica la Funzione Finestra di Hamming:
bb[i] *= AMP_HAMM * (0.54 - 0.46 * Cos(2.0 * Pi * i / (TEMPO_DISCRETO - 1)))
Next
End
In questo codice utilizzeremo un'altra formula per generare i dati dell'onda sinusoidale, i quali in questo caso avranno una definizione a 16-bit. Inoltre al termine dell'esecuzione audio dell'onda sinusoidale, i dati audio grezzi saranno salvati in un file.
Private Const AMPIEZZA As Byte = 128
Private Const CAMPIONAMENTO As Integer = 44100
Private Const FREQUENZA As Short = 440
Private Const DURATA As Single = 10.0
Private Const AMP_HAMM As Single = 32.0
Private Const TEMPO_DISCRETO As Integer = 32768
Public Sub Main()
Dim disp As AlcDevice
Dim cont As AlcContext
Dim src, buffer As Integer[]
Dim err As Boolean
Dim dati As New Short[]
disp = Alc.OpenDevice(Null)
If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !")
cont = Alc.CreateContext(disp)
If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
err = cont.MakeCurrent()
If err = False Then Error.Raise("Impossibile creare il contesto audio !")
src = Al.GenSources(1)
If IsNull(src) Then Error.Raise("Errore !")
buffer = Al.GenBuffers(1)
If IsNull(buffer) Then Error.Raise("Errore !")
Onda(dati)
Al.BufferData(buffer[0], al.FORMAT_MONO16, dati.Data, dati.Count, CAMPIONAMENTO)
Al.Sourcei(src[0], Al.BUFFER, buffer[0])
Al.SourcePlay(src[0])
Wait DURATA
Al.SourceStop(src[0])
' Libera la memoria:
Al.DeleteBuffers(buffer)
Al.DeleteSources(src)
Alc.DestroyContext(cont)
Alc.CloseDevice(disp)
' Va a generare il file contenente i dati audio grezzi:
CreaFileDatiGrezzi(dati)
End
Private Function Onda(data As Short[]) ' Crea i dati dell'onda sinusoidale
Dim k As Integer
For k = 0 To (DURATA * CAMPIONAMENTO) - 1
data.Push(AMPIEZZA * Sin(2.0 * k * Pi * 1.0 / 64.0 + 0.4))
' Applica la Funzione Finestra di Hamming:
data[k] *= AMP_HAMM * (0.54 - 0.46 * Cos(2.0 * Pi * k / (TEMPO_DISCRETO - 1)))
Next
End
Private Procedure CreaFileDatiGrezzi(grezzi As Short[])
Dim fl As File
fl = Open "/tmp/dati_audio" For Create
' Salva i dati audio grezzi nel file:
grezzi.Write(fl, 0, grezzi.Count)
fl.Close
End