La gestione mediante il componente gb.openal
Il componente gb.openal utilizza le risorse dell'API di Openal.
E' possibile eseguire un file audio mediante le risorse delle Classi Al ed Alure |1| del componente gb.openal.
Eseguire un file audio con le risorse della Classe Al e della Classe Alure
Vi sono almeno tre modalità per eseguire un file audio mediante le risorse della Classe Al e della Classe Alure del componente gb.openal.
E' possibile riprodurre file audio dei seguenti tipi:
- WAV;
- MP3;
- OGG.
1a modalità
Private src As Integer[] Private ast As Alurestream Public Sub Form_Open() Dim err As Boolean ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") End Public Sub Button1_Click() ' Avvia l'esecuzione del file audio Dim fileAudio As String = "/percorso/del/file/audio" Dim lungh As Integer Dim l As Byte = 1 If IsNull(src) = False Then al.DeleteSources(src) src = Al.GenSources(1) ' Individua la lunghezza del file audio caricato da eseguire: lungh = Stat(fileAudio).Size ' Se il file audio è un "mp3" o un "ogg", allora il valore della variabile "lungh" ' deve essere moltiplicato almeno per 4, altrimenti l'esecuzione audio terminerà anticipatamente: If Lower(File.Ext(fileAudio)) <> "wav" Then l = 4 ast = Alure.CreateStreamFromFile(fileAudio, lungh * l, 0) ' Esegue il flusso di dati audio. ' Il terzo parametro della funzione rappresenta il numero dei buffer utilizzati da accodare alla fonte di "OpenAL". ' Ogni buffer verrà riempito con la lunghezza del "chunk" specificato quando il flusso è stato creato. ' Tale valore nell'esecuzione di un file audio deve essere di almeno 2. Alure.PlaySourceStream(src[0], ast, 3, 0) End Public Sub Button2_Click() ' Arresta l'esecuzione del file audio If IsNull(ast) Then Return Alure.StopSource(src[0]) End Public Sub Button3_Click() ' Arresta l'esecuzione del file audio e chiude la finestra del programma If IsNull(ast) = False Then Alure.DestroyStream(ast) al.DeleteSources(src) Alure.StopSource(src[0]) Endif Alure.ShutdownDevice() Me.Close End
2a modalità
Private source As Integer Public Sub Form_Open() Dim err As Boolean ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") End Public Sub Button1_Click() ' Avvia l'esecuzione del file audio Dim buffer As Integer buffer = alure.CreateBufferFromFile("/percorso/del/file/audio") ' Crea una sorgente sonora: source = al.GenSources(1)[0] ' Viene utilizzata la variabile "buffer" per riempire la sorgente. ' Il secondo argomento indica al buffer di fornire campioni sonori:</font> al.Sourcei(source, al.BUFFER, buffer) ' Esegue il flusso di dati audio. al.SourcePlay(source) End Public Sub ToggleButton1_Click() If ToggleButton1.Value ' Mette in pausa l'esecuzione del file audio al.SourcePause(source) Else ' Fa proseguire l'esecuzione del file audio al.SourcePlay(source) Endif End Public Sub Button2_Click() ' Arresta l'esecuzione del file audio al.SourceStop(source) End
3a modalità
Private ags As Integer Public Sub Button1_Click() ' Avvia l'esecuzione del file audio Dim err As Boolean Dim fileAudio As String = "/percorso/del/file/audio" Dim agb As Integer ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") ' Genera le sorgenti sonore ed i buffer: ags = al.GenSources(1)[0] agb = al.GenBuffers(ags)[0] err = alure.BufferDataFromFile(fileAudio, agb) If err = False Then Error.Raise("Impossibile creare un buffer-data dal file audio !") al.Sourcei(ags, al.BUFFER, agb) ' Esegue il file audio: al.SourcePlay(ags) End Public Sub ToggleButton1_Click() If ToggleButton1.Value ' Mette in pausa l'esecuzione del file audio al.SourcePause(ags) Else ' Fa proseguire l'esecuzione del file audio al.SourcePlay(ags) Endif End Public Sub Button2_Click() ' Arresta l'esecuzione del file audio al.SourceStop(ags) End
Caso di applicazione a riga di comando
Nel caso in cui l'applicazione per l'esecuzione di file audio sia stata realizzata senza componenti grafici, e dunque a riga di comando, al termine del codice sarà assolutamente necessario prevedere un ciclo.
E' possibile porre in Pausa l'esecuzione immettendo nel Terminale o nell'apposito spazio della console il carattere "p" e quindi premendo il tasto Invio. Per riprendere l'esecuzione basterà premere il solo tasto "Invio". E' altresì possibile arrestare l'esecuzione immettendo nel Terminale o nell'apposito spazio della console uno o più caratteri (ovviamente diversi dalla lettera "p"), quindi premendo il tasto Invio.
1a modalità
Private s As String Public Sub Main() Dim err As Boolean Dim fileAudio As String Dim src, lungh As Integer Dim ast As Alurestream Dim l As Byte = 1 fileAudio = "/percorso/del/file/audio" ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") src = Al.GenSources(1)[0] lungh = Stat(fileAudio).Size If Lower(File.Ext(fileAudio)) <> "wav" Then l = 4 ast = Alure.CreateStreamFromFile(fileAudio, lungh * l, 0) Alure.PlaySourceStream(src, ast, 3, 0) ' Inviando il carattere "p" dal Terminale o dalla console, l'esecuzione è posta in "Pausa", ' inviando ogni altro carattere essa viene terminata: Do Input s If s = "p" Then Pausa(src) Loop Until s <> Null Alure.DestroyStream(ast) al.DeleteSources([src]) Alure.StopSource(src) Alure.ShutdownDevice() End Private Procedure Pausa(sAl As Integer) Dim ripresa As String al.SourcePause(sAl) Print "Pausa !" ' Per riprendere l'esecuzione, è sufficiente premere il tasto "Invio": Input ripresa al.SourcePlayv([sal]) Print "Riprende esecuzione." s = Null End
2a modalità
Private s As String Public Sub Main() Dim err As Boolean Dim buffer, source As Integer ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") buffer = alure.CreateBufferFromFile("/percorso/del/file/audio") ' Crea una sorgente sonora: source = al.GenSources(1)[0] ' Viene utilizzata la variabile "buffer" per riempire la sorgente. ' Il secondo argomento indica al buffer di fornire campioni sonori:</font> al.Sourcei(source, al.BUFFER, buffer) ' Esegue il flusso di dati audio. al.SourcePlay(source) ' Inviando il carattere "p" dal Terminale o dalla console, l'esecuzione è posta in "Pausa", ' inviando ogni altro carattere essa viene terminata: Do Input s If s = "p" Then Pausa(source) Loop Until s <> Null al.DeleteBuffers([buffer]) al.DeleteSources([source]) Alure.StopSource(source) Alure.ShutdownDevice() End Private Procedure Pausa(sAl As Integer) Dim ripresa As String al.SourcePause(sAl) Print "Pausa !" ' Per riprendere l'esecuzione, è sufficiente premere il tasto "Invio": Input ripresa al.SourcePlay(sAl) Print "Riprende esecuzione." s = Null End
3a modalità
Private s As String Public Sub Main() Dim err As Boolean Dim fileAudio As String Dim agb, ags As Integer fileAudio = "/percorso/del/file/audio" ' Inizializza la libreria "Alure": err = Alure.InitDevice(Null, Null) If err = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !") ags = al.GenSources(1)[0] agb = al.GenBuffers(ags)[0] err = alure.BufferDataFromFile(fileAudio, agb) If err = False Then Error.Raise("Impossibile creare un buffer-data dal file audio !") al.Sourcei(ags, al.BUFFER, agb) al.SourcePlay(ags) ' Inviando il carattere "p" dal Terminale o dalla console, l'esecuzione è posta in "Pausa", ' inviando ogni altro carattere essa viene terminata: Do Input s If s = "p" Then Pausa(ags) Loop Until s <> Null al.DeleteBuffers([agb]) al.DeleteSources([ags]) Alure.StopSource(ags) Alure.ShutdownDevice() End Private Procedure Pausa(sAl As Integer) Dim ripresa As String al.SourcePause(sAl) Print "Pausa !" ' Per riprendere l'esecuzione, è sufficiente premere il tasto "Invio": Input ripresa al.SourcePlay(sAl) Print "Riprende esecuzione." s = Null End
Senza uso della Classe Alure e caricando direttamente i dati audio grezzi nel buffer audio
In quest'altra modalità non si farà uso della Classe Alure e si provvederà a caricare i dati audio grezzi di un file WAV nel Buffer audio impostato con la Classe Al. Inoltre il dispositivo ed il contesto audio saranno impostati mediante la Classe Alc .
Public Struct InfoWAV fileWAV As String canali As Short frequenza As Integer bit As Short block_align As Short durata As Float sonora As Byte[] End Struct Public Sub Main() Dim dispositivo As AlcDevice Dim contesto As AlcContext Dim src As Integer[] Dim buffer As Integer[] Dim err As Boolean Dim iw As New InfoWAV Dim Formato_audio As Short ' Imposta il dispositivo ed il contesto audio con la Classe "Alc": dispositivo = Alc.OpenDevice(Null) contesto = Alc.CreateContext(dispositivo) err = contesto.MakeCurrent() If err = False Then Error.Raise("Impossibile creare il contesto audio !") src = Al.GenSources(1) ' Imposta il buffer audio: buffer = Al.GenBuffers(1) iw.fileWAV = "/percorso/del/file.wav" datiAudio(iw) Select Case iw.canali + iw.bit Case 9 Formato_audio = 4352 Case 10 Formato_audio = 4354 Case 17 Formato_audio = 4353 Case 18 Formato_audio = 4355 End Select ' I dati audio grezzi del file wav sono caricati nel buffer audio: Al.BufferData(buffer[0], Formato_audio, iw.sonora.ToString(0, iw.sonora.Count), iw.sonora.Count, iw.frequenza) ' 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 del brano: Sleep iw.durata ' Va in chiusura: Al.DeleteBuffers(buffer) Al.DeleteSources(src) Alc.DestroyContext(contesto) Alc.CloseDevice(dispositivo) End Private Function datiAudio(iwav As InfoWAV) Dim fl As File Dim d As Short Print "File wav caricato:";; iwav.fileWAV ' Carica il file audio Wav: fl = Open iwav.fileWAV For Read d = InStr(File.Load(iwav.fileWAV), "data") iwav.sonora = New Byte[Lof(fl) - (d + 7)] ' Spostiamo il puntatore all'interno del flusso del file sul primo byte successivo all'header del file wav, ' per caricare tutti i datri audio grezzi: Seek #fl, d + 7 iwav.sonora.Read(fl, 0, Lof(fl) - (d + 7)) ' Leggiamo il numero dei canali: Seek #fl, 22 iwav.canali = Read #fl As Short Print "Numero canali:";; iwav.canali ' Leggiamo la frequenza di campionamento dei dati audio: Seek #fl, 24 iwav.frequenza = Read #fl As Integer Print "Frequenza di campionamento: hz";; iwav.frequenza ' Leggiamo il valore del "block align": Seek #fl, 32 iwav.block_align = Read #fl As Short ' Leggiamo la risoluzione bit del campionamento: Seek #fl, 34 iwav.bit = Read #fl As Short Print "Risoluzione:";; iwav.bit;; "bit" ' Calcoliamo la durata del brano audio: iwav.durata = (iwav.sonora.Count / iwav.block_align) / iwav.frequenza Print "Durata esecuzione:";; CStr(Date(0, 0, 0, 0, 0, 0, iwav.durata * 1000)) fl.Close End
Note
[1] La Classe Alure del componente gb.openal consente di gestire le funzioni di ALURE, che è una libreria di supporto di Openal.