Differenze tra le versioni di "Generare un'onda sinusoidale con il componente gb.openal"
Da Gambas-it.org - Wikipedia.
(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 18: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