Differenze tra le versioni di "Generare un'onda sinusoidale con il componente gb.openal"

Da Gambas-it.org - Wikipedia.
 
(5 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Utilizzando le risorse della Classe " ''Alc'' " del Componente ''gb.openal'' di Gambas, è possibile eseguire un'onda sinusoidale, i cui dati saranno realizzati mediante appsota formula matematica.
+
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()
+
  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 Formato_audio As Integer
 
 
   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)
+
  disp = Alc.OpenDevice(Null)
  If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !")
+
  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)
+
  cont = Alc.CreateContext(disp)
  If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
+
  If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
 
+
 
  err = cont.MakeCurrent()
+
  err = cont.MakeCurrent()
  If err = False Then Error.Raise("Impossibile creare il contesto audio !")
+
  If err = False Then Error.Raise("Impossibile creare il contesto audio !")
 
+
 
  src = Al.GenSources(1)
+
  src = Al.GenSources(1)
  If IsNull(src) Then Error.Raise("Errore !")
+
  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)
+
  buffer = Al.GenBuffers(1)
  If IsNull(buffer) Then Error.Raise("Errore !")
+
  If IsNull(buffer) Then Error.Raise("Errore !")
 
 
  Onda(dati)
 
 
    
 
    
  Formato_audio = 4352
+
  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], Formato_audio, dati.Data, dati.Count, CAMPIONAMENTO)
+
  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])
+
  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])
+
  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>
  Sleep DURATA
+
  Wait DURATA
 
+
  al.SourceStop(src[0])
+
  Al.SourceStop(src[0])
 
    
 
    
 
  <FONT Color=gray>' ''Libera la memoria:''</font>
 
  <FONT Color=gray>' ''Libera la memoria:''</font>
  Al.DeleteBuffers(buffer)
+
  Al.DeleteBuffers(buffer)
  Al.DeleteSources(src)
+
  Al.DeleteSources(src)
  Alc.DestroyContext(cont)
+
  Alc.DestroyContext(cont)
  Alc.CloseDevice(disp)
+
  Alc.CloseDevice(disp)
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Function Onda(bb As Byte[])  <FONT Color=gray>' ''Crea i dati dell'onda sinusoidale''</font>
+
  Private Function Onda(bb As Byte[])  <FONT Color=gray>' ''Crea i dati dell'onda sinusoidale''</font>
 
+
 
   Dim i As Integer
 
   Dim i As Integer
 
    
 
    
  For i = 0 To (DURATA * 2 * CAMPIONAMENTO) - 1
+
  For i = 0 To (DURATA * 2 * CAMPIONAMENTO) - 1
    bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi)))))
+
    bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi)))))
  Next
+
  Next
 
    
 
    
  '''End'''
+
  End
  
  
  
In quest'altro codice, simile al precedente, appllicheremo ai dati dell'onda sinusoidale l'effetto della ''[https://it.wikipedia.org/wiki/Funzione_finestra Funzione Finestra di Hamming]'':
+
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 AMPIEZZA As Byte = 127
 
  Private Const FREQUENZA As Short = 440
 
  Private Const FREQUENZA As Short = 440
Riga 83: Riga 80:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  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 Formato_audio As Integer
 
 
   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)
+
  disp = Alc.OpenDevice(Null)
  If IsNull(disp) Then Error.Raise("Impossibile configurare il dispositivo audio !")
+
  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)
+
  cont = Alc.CreateContext(disp)
  If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
+
  If IsNull(cont) Then Error.Raise("Impossibile configurare il contesto audio !")
 
    
 
    
  err = cont.MakeCurrent()
+
  err = cont.MakeCurrent()
  If err = False Then Error.Raise("Impossibile creare il contesto audio !")
+
  If err = False Then Error.Raise("Impossibile creare il contesto audio !")
 
    
 
    
  src = Al.GenSources(1)
+
  src = Al.GenSources(1)
  If IsNull(src) Then Error.Raise("Errore !")
+
  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)
+
  buffer = Al.GenBuffers(1)
  If IsNull(buffer) Then Error.Raise("Errore !")
+
  If IsNull(buffer) Then Error.Raise("Errore !")
 
 
  Onda(dati)
 
 
 
  Formato_audio = 4352
 
 
    
 
    
 +
  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], Formato_audio, dati.Data, dati.Count, CAMPIONAMENTO)
+
  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])
+
  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])
+
  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>
  Sleep DURATA
+
  Wait DURATA
 
    
 
    
  al.SourceStop(src[0])
+
  Al.SourceStop(src[0])
 
    
 
    
 
  <FONT Color=gray>' ''Libera la memoria:''</font>
 
  <FONT Color=gray>' ''Libera la memoria:''</font>
  Al.DeleteBuffers(buffer)
+
  Al.DeleteBuffers(buffer)
  Al.DeleteSources(src)
+
  Al.DeleteSources(src)
  Alc.DestroyContext(cont)
+
  Alc.DestroyContext(cont)
  Alc.CloseDevice(disp)
+
  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 * 2 * 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'''
+
  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()
 
   
 
   
'''Private''' Function Onda(bb As Byte[])  <FONT Color=gray>' ''Crea i dati dell'onda sinusoidale''</font>
+
  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 !")
 
    
 
    
   Dim i As Integer
+
   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)
 +
 
 +
<FONT Color=gray>' ''Va a generare il file contenente i dati audio grezzi:''</font>
 +
  CreaFileDatiGrezzi(dati)
 
    
 
    
  For i = 0 To (DURATA * 2 * CAMPIONAMENTO) - 1
+
End
    bb.Push(CByte(128 + AMPIEZZA * Sin(CFloat(i / CAMPIONAMENTO * FREQUENZA * (2 * Pi)))))
+
 +
 +
Private Function Onda(data As Short[])  ' Crea i dati dell'onda sinusoidale
 +
 +
  Dim k As Integer
 +
   
 +
  For k = 0 To (DURATA * 2 * 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>
 
  <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)))
+
    data[k] *= AMP_HAMM * (0.54 - 0.46 * Cos(2.0 * Pi * k / (TEMPO_DISCRETO - 1)))
   Next
+
  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'''
+
  End

Versione attuale delle 12:45, 26 lug 2023

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 * 2 * 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 * 2 * 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 * 2 * 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