Differenze tra le versioni di "Eseguire i file Midi con le funzioni esterne dell'API di Alure"

Da Gambas-it.org - Wikipedia.
 
(6 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
 
'''ALURE''' è una libreria di utilità per aiutare a gestire le operazioni più comuni con applicazioni ''OpenAL''. Questo include l'enumerazione e l'inizializzazione del dispositivo, il caricamento del file, e l'esecuzione. Lo scopo di questa [http://it.wikipedia.org/wiki/Application_programming_interface API] è quello di fornire funzionalità pre-organizzate per facilitare e velocizzare la programmazione dello sviluppatore.
 
'''ALURE''' è una libreria di utilità per aiutare a gestire le operazioni più comuni con applicazioni ''OpenAL''. Questo include l'enumerazione e l'inizializzazione del dispositivo, il caricamento del file, e l'esecuzione. Lo scopo di questa [http://it.wikipedia.org/wiki/Application_programming_interface API] è quello di fornire funzionalità pre-organizzate per facilitare e velocizzare la programmazione dello sviluppatore.
 
  
 
La libreria condivisa contenente le funzioni esterne dell'API di ''OpenAlure'', e che dovrà essere richiamata in Gambas, è attualmente la seguente:
 
La libreria condivisa contenente le funzioni esterne dell'API di ''OpenAlure'', e che dovrà essere richiamata in Gambas, è attualmente la seguente:
Riga 9: Riga 8:
 
La documentazione ufficiale afferma che questa funzione specifica il ''patchset'' da utilizzare per i flussi MIDI. Per impostazione predefinita, il decoder ''FluidSynth'' ne cercherà uno nella variabile d'ambiente ''FLUID_SOUNDFONT'', ma questo può essere usato utilizzarne anche uno diverso. Sui flussi non-MIDI, questa funzione, ancorché impostata, non ha alcun effetto.
 
La documentazione ufficiale afferma che questa funzione specifica il ''patchset'' da utilizzare per i flussi MIDI. Per impostazione predefinita, il decoder ''FluidSynth'' ne cercherà uno nella variabile d'ambiente ''FLUID_SOUNDFONT'', ma questo può essere usato utilizzarne anche uno diverso. Sui flussi non-MIDI, questa funzione, ancorché impostata, non ha alcun effetto.
 
<BR>V'è da precisare che il ''patchset'' sopra mensionato è sostanzialmente un file contenente il banco di suoni (''soundfont bank'') con estensione .sf2 utilizzato normalmente dai softsynth per ottenere l'ascolto effettivo dei flussi Midi. Pertanto sarà sufficiente in quel parametro indicare il percorso del file ''soundfont'' .sf2 che si intende utilizzare.
 
<BR>V'è da precisare che il ''patchset'' sopra mensionato è sostanzialmente un file contenente il banco di suoni (''soundfont bank'') con estensione .sf2 utilizzato normalmente dai softsynth per ottenere l'ascolto effettivo dei flussi Midi. Pertanto sarà sufficiente in quel parametro indicare il percorso del file ''soundfont'' .sf2 che si intende utilizzare.
 
  
 
Mostriamo di seguito un semplice codice per ottenere l'esecuzione, la pausa, la ripresa e l'arresto di file Midi:
 
Mostriamo di seguito un semplice codice per ottenere l'esecuzione, la pausa, la ripresa e l'arresto di file Midi:
  '''Private''' isdone As Integer
+
  Private isdone As Integer
  '''Private''' src As Integer
+
  Private src As Integer
  '''Private''' streamP As Pointer
+
  Private streamP As Pointer
 
   
 
   
 
   
 
   
Riga 24: Riga 22:
 
  ' ''The name and attribute list would be the same as what’s passed to alcOpenDevice and alcCreateContext respectively.''
 
  ' ''The name and attribute list would be the same as what’s passed to alcOpenDevice and alcCreateContext respectively.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private''' Extern alureInitDevice(name As String, attribs As String) As Boolean
+
  Private Extern alureInitDevice(name As String, attribs As String) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''void alGenSources(Alsizei n, ALuint *sources)''</font>
 
  <FONT color=gray>' ''void alGenSources(Alsizei n, ALuint *sources)''</font>
  '''Private''' Extern alGenSources(n As Integer, sources As Pointer) In "libalut:0.1.0"
+
  Private Extern alGenSources(n As Integer, sources As Pointer) In "libalut:0.1.0"
 
<FONT color=gray>' ''ALboolean alureStreamSizeIsMicroSec(ALboolean useUS)''
 
' ''Specifies if the chunk size value given to the alureCreateStream functions is in bytes (default) or microseconds.''
 
' ''Returns: Previously set value.''</font>
 
'''Private''' Extern alureStreamSizeIsMicroSec(useUS As Boolean) As Boolean
 
 
   
 
   
 
  <FONT color=gray>' ''alureStream* alureCreateStreamFromFile(Const ALchar * fname, ALsizei chunkLength, ALsizei numBufs, ALuint * bufs)''
 
  <FONT color=gray>' ''alureStream* alureCreateStreamFromFile(Const ALchar * fname, ALsizei chunkLength, ALsizei numBufs, ALuint * bufs)''
Riga 39: Riga 32:
 
  ' ''then place the new IDs into the provided storage, before returning.  Requires an active context.''
 
  ' ''then place the new IDs into the provided storage, before returning.  Requires an active context.''
 
  ' ''Returns: An opaque handle used To control the opened stream, Or Null On error.''</font>
 
  ' ''Returns: An opaque handle used To control the opened stream, Or Null On error.''</font>
  '''Private''' Extern alureCreateStreamFromFile(fname As String, chunkLength As Integer, numBufs As Integer, bufs As Pointer) As Pointer
+
  Private Extern alureCreateStreamFromFile(fname As String, chunkLength As Integer, numBufs As Integer, bufs As Pointer) As Pointer
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alurePlaySourceStream(ALuint source, alureStream * stream, ALsizei numBufs, ALsizei loopcount, void( * eos_callback)(void * userdata, ALuint source), void * userdata)''
 
  <FONT color=gray>' ''ALboolean alurePlaySourceStream(ALuint source, alureStream * stream, ALsizei numBufs, ALsizei loopcount, void( * eos_callback)(void * userdata, ALuint source), void * userdata)''
Riga 49: Riga 42:
 
  ' ''It will also be called if an error occured and playback terminated.''
 
  ' ''It will also be called if an error occured and playback terminated.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private''' Extern alurePlaySourceStream(source As Integer, strePnt As Pointer, numBufs As Integer, loopcount As Integer, eos_callback As Pointer, userdata As Pointer) As Boolean
+
  Private Extern alurePlaySourceStream(source As Integer, strePnt As Pointer, numBufs As Integer, loopcount As Integer, eos_callback As Pointer, userdata As Pointer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alureSetStreamPatchset(alureStream * stream, Const ALchar * patchset)''
 
  <FONT color=gray>' ''ALboolean alureSetStreamPatchset(alureStream * stream, Const ALchar * patchset)''
Riga 55: Riga 48:
 
  ' ''but this can be used to change it to something different.  On non-MIDI streams, this has no effect.''
 
  ' ''but this can be used to change it to something different.  On non-MIDI streams, this has no effect.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private''' Extern alureSetStreamPatchset(strePnt As Pointer, patchset As String) As Boolean
+
  Private Extern alureSetStreamPatchset(strePnt As Pointer, patchset As String) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''void alureUpdate(void)''
 
  <FONT color=gray>' ''void alureUpdate(void)''
Riga 61: Riga 54:
 
  ' ''This makes sure that sources played with alurePlaySourceStream are kept fed from their associated stream, and sources played with alurePlaySource are still playing.''
 
  ' ''This makes sure that sources played with alurePlaySourceStream are kept fed from their associated stream, and sources played with alurePlaySource are still playing.''
 
  ' ''It will call their callbacks as needed.''</font>
 
  ' ''It will call their callbacks as needed.''</font>
  '''Private''' Extern alureUpdate()
+
  Private Extern alureUpdate()
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alureStopSource(ALuint source, ALboolean run_callback)''
 
  <FONT color=gray>' ''ALboolean alureStopSource(ALuint source, ALboolean run_callback)''
 
  ' ''Stops the specified source ID, and any associated stream.''
 
  ' ''Stops the specified source ID, and any associated stream.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private''' Extern alureStopSource(source As Integer, run_callback As Boolean) As Boolean
+
  Private Extern alureStopSource(source As Integer, run_callback As Boolean) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''void alDeleteSources(ALsizei n, ALuint * sources)''
 
  <FONT color=gray>' ''void alDeleteSources(ALsizei n, ALuint * sources)''
 
  ' ''This function deletes one or more sources.''</font>
 
  ' ''This function deletes one or more sources.''</font>
  '''Private''' Extern alDeleteSources(n As Integer, sources As Pointer) In "libalut:0.1.0"
+
  Private Extern alDeleteSources(n As Integer, sources As Pointer) In "libalut:0.1.0"
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alureDestroyStream(alureStream * stream, ALsizei numBufs, ALuint * bufs)'
 
  <FONT color=gray>' ''ALboolean alureDestroyStream(alureStream * stream, ALsizei numBufs, ALuint * bufs)'
 
  ' ''Closes an opened stream.''
 
  ' ''Closes an opened stream.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private''' Extern alureDestroyStream(strePnt As Pointer, numBufs As Integer, bufs As Pointer) As Boolean
+
  Private Extern alureDestroyStream(strePnt As Pointer, numBufs As Integer, bufs As Pointer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alureShutdownDevice(void)''
 
  <FONT color=gray>' ''ALboolean alureShutdownDevice(void)''
 
  ' ''Destroys the current context and closes its associated device.''
 
  ' ''Destroys the current context and closes its associated device.''
 
  ' ''Returns: AL_FALSE On error.''</font>
 
  ' ''Returns: AL_FALSE On error.''</font>
  '''Private'' Extern alureShutdownDevice() As Boolean
+
  Private Extern alureShutdownDevice() As Boolean
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alurePauseSource(ALuint source)''
 
  <FONT color=gray>' ''ALboolean alurePauseSource(ALuint source)''
 
  ' ''Pauses the specified source ID, and any associated stream. Returns AL_FALSE On Error.''</font>
 
  ' ''Pauses the specified source ID, and any associated stream. Returns AL_FALSE On Error.''</font>
  '''Private''' Extern alurePauseSource(source As Integer) As Boolean
+
  Private Extern alurePauseSource(source As Integer) As Boolean
 
   
 
   
 
  <FONT color=gray>' ''ALboolean alureResumeSource(ALuint source)''
 
  <FONT color=gray>' ''ALboolean alureResumeSource(ALuint source)''
 
  ' ''Resumes the specified source ID after being paused. Returns AL_FALSE On Error.''</font>
 
  ' ''Resumes the specified source ID after being paused. Returns AL_FALSE On Error.''</font>
  '''Private''' Extern alureResumeSource(source As Integer) As Boolean
+
  Private Extern alureResumeSource(source As Integer) As Boolean
 
   
 
   
 +
 +
<FONT color=gray>' ''void exit(int status)''
 +
' ''Terminates the calling process immediately.''</font>
 +
Private Extern C_exit(status As Integer) In "libc:6" Exec "exit"
 +
 
 
   
 
   
 
  '''Public''' Sub Button1_Click()
 
  '''Public''' Sub Button1_Click()
 
   
 
   
  Dim ver As Boolean
+
  Dim ver As Boolean
  Dim percorsoFile As String = "''percorso_del_file.mid''"
+
  Dim percorsoFile As String = "''/percorso/del/file.mid''"
  Dim lungh As Integer
+
  Dim lungh As Integer
+
  Dim tm As Date
+
 
 
   ver = alureInitDevice(Null, Null)
 
   ver = alureInitDevice(Null, Null)
 
   If ver = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !")
 
   If ver = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !")
+
 
 
   alGenSources(1, VarPtr(src))
 
   alGenSources(1, VarPtr(src))
 
    
 
    
  ver = alureStreamSizeIsMicroSec(False)
 
  If ver = False Then Error.Raise("Impossibile specificare il valore della dimensione di un chunk !")
 
 
 
   lungh = Stat(percorsoFile).Size
 
   lungh = Stat(percorsoFile).Size
 
    
 
    
Riga 111: Riga 106:
 
  ' ''è opportuno passare il valore del secondo parametro almeno pari alla dimensione del file:''</font>
 
  ' ''è opportuno passare il valore del secondo parametro almeno pari alla dimensione del file:''</font>
 
   streamP = alureCreateStreamFromFile(percorsoFile, lungh, 0, Null)
 
   streamP = alureCreateStreamFromFile(percorsoFile, lungh, 0, Null)
   If IsNull(streamP) Then Error.Raise("Impossibile caricare il file Midi !")
+
   If streamP == 0 Then Error.Raise("Impossibile caricare il file Midi !")
 
    
 
    
   ver = alureSetStreamPatchset(streamP, "''percorso_del_file_soundfont.sf2")
+
   ver = alureSetStreamPatchset(streamP, "''/percorso/del/file/soundfont.sf2")
 
   If ver = False Then Error.Raise("Impossibile impostare il file del banco-suoni !")
 
   If ver = False Then Error.Raise("Impossibile impostare il file del banco-suoni !")
 
   
 
   
Riga 121: Riga 116:
 
   ver = alurePlaySourceStream(src, streamP, <FONT color=#B22222>3</font>, 0, <FONT color=darkgreen>eos_callback</font>, Null)
 
   ver = alurePlaySourceStream(src, streamP, <FONT color=#B22222>3</font>, 0, <FONT color=darkgreen>eos_callback</font>, Null)
 
   If ver = False Then Error.Raise("Impossibile eseguire il flusso dati audio !")
 
   If ver = False Then Error.Raise("Impossibile eseguire il flusso dati audio !")
 
+
   While isdone = 0
+
  tm = Now
 +
 +
   While isdone == 0
 +
    Write "\r\e[0mTempo trascorso: \e[31m" & Str(Time(0, 0, 0, DateDiff(tm, Now, gb.Millisecond)))
 
     Wait 0.01
 
     Wait 0.01
 
     alureUpdate()
 
     alureUpdate()
 
   Wend
 
   Wend
 
+
 
   
+
  <FONT color=gray>' ''Va in chiusura:''</font>
   alureStopSource(src, False)
+
   AlureStop()
  alDeleteSources(1, VarPtr(src))
 
  alureDestroyStream(streamP, 0, Null)
 
  alureShutdownDevice()
 
 
 
   isdone = 0
 
   isdone = 0
+
 
 
  '''End'''
 
  '''End'''
 
 
 
   
 
   
 
  '''Private''' Function eos_callback(unused As Pointer, unused2 As Integer)
 
  '''Private''' Function eos_callback(unused As Pointer, unused2 As Integer)
Riga 144: Riga 136:
 
    
 
    
 
  '''End'''
 
  '''End'''
 
 
   
 
   
 
  <FONT color=gray>' ''Mette in pausa l'esecuzione:''</font>
 
  <FONT color=gray>' ''Mette in pausa l'esecuzione:''</font>
Riga 163: Riga 154:
 
  '''Public''' Sub Button4_Click()
 
  '''Public''' Sub Button4_Click()
 
   
 
   
   alureStopSource(src, False)
+
   AlureStop()
  alDeleteSources(1, VarPtr(src))
+
  alureDestroyStream(streamP, 0, Null)
+
'''End'''
  alureShutdownDevice()
+
 +
<FONT color=gray>' ''Arresta l'esecuzione e chiude la finestra del programma:''</font>
 +
'''Public''' Sub Button5_Click()
 +
 
 +
  AlureStop()
 +
 +
  Me.Close
 +
  C_exit(0)
 +
 
 +
'''End'''
 +
 +
'''Private''' Procedure AlureStop()
 +
 +
  alureStopSource(src, False)
 +
  alDeleteSources(1, VarPtr(src))
 +
  alureDestroyStream(streamP, 0, Null)
 +
  alureShutdownDevice()
 
   
 
   
 
  '''End'''
 
  '''End'''
Riga 173: Riga 180:
  
 
=Riferimenti=
 
=Riferimenti=
* Il sito dell'[http://kcat.strangesoft.net/alure-docs/files/alure-cpp.html API di Alure]
+
* https://kcat.tomasu.net/alure-docs/index/Functions.html

Versione attuale delle 01:09, 28 ago 2022

ALURE è una libreria di utilità per aiutare a gestire le operazioni più comuni con applicazioni OpenAL. Questo include l'enumerazione e l'inizializzazione del dispositivo, il caricamento del file, e l'esecuzione. Lo scopo di questa API è quello di fornire funzionalità pre-organizzate per facilitare e velocizzare la programmazione dello sviluppatore.

La libreria condivisa contenente le funzioni esterne dell'API di OpenAlure, e che dovrà essere richiamata in Gambas, è attualmente la seguente:

libalure.so.1.2.0

Questa libreria di funzioni consente di eseguire anche file Midi. Per ottenere tale funzionalità, è necessario impostare la seguente funzione:

ALboolean alureSetStreamPatchset(alureStream * stream, const ALchar * patchset)

La documentazione ufficiale afferma che questa funzione specifica il patchset da utilizzare per i flussi MIDI. Per impostazione predefinita, il decoder FluidSynth ne cercherà uno nella variabile d'ambiente FLUID_SOUNDFONT, ma questo può essere usato utilizzarne anche uno diverso. Sui flussi non-MIDI, questa funzione, ancorché impostata, non ha alcun effetto.
V'è da precisare che il patchset sopra mensionato è sostanzialmente un file contenente il banco di suoni (soundfont bank) con estensione .sf2 utilizzato normalmente dai softsynth per ottenere l'ascolto effettivo dei flussi Midi. Pertanto sarà sufficiente in quel parametro indicare il percorso del file soundfont .sf2 che si intende utilizzare.

Mostriamo di seguito un semplice codice per ottenere l'esecuzione, la pausa, la ripresa e l'arresto di file Midi:

Private isdone As Integer
Private src As Integer
Private streamP As Pointer


Library "libalure:1.2.0"


' ALboolean alureInitDevice(const ALCchar * name, Const ALCint * attribs)
' Opens the named device, creates a context with the given attributes, and sets that context as current.
' The name and attribute list would be the same as what’s passed to alcOpenDevice and alcCreateContext respectively.
' Returns: AL_FALSE On error.
Private Extern alureInitDevice(name As String, attribs As String) As Boolean

' void alGenSources(Alsizei n, ALuint *sources)
Private Extern alGenSources(n As Integer, sources As Pointer) In "libalut:0.1.0"

' alureStream* alureCreateStreamFromFile(Const ALchar * fname, ALsizei chunkLength, ALsizei numBufs, ALuint * bufs)
' Opens a file and sets it up for streaming.  The given chunkLength is the number of bytes, or microseconds worth of bytes if alureStreamSizeIsMicroSec was last called with AL_TRUE,
' each buffer will fill with.  ALURE will optionally generate the specified number of buffer objects, fill them with the beginning of the data,
' then place the new IDs into the provided storage, before returning.  Requires an active context.
' Returns: An opaque handle used To control the opened stream, Or Null On error.
Private Extern alureCreateStreamFromFile(fname As String, chunkLength As Integer, numBufs As Integer, bufs As Pointer) As Pointer

' ALboolean alurePlaySourceStream(ALuint source, alureStream * stream, ALsizei numBufs, ALsizei loopcount, void( * eos_callback)(void * userdata, ALuint source), void * userdata)
' Starts playing a stream, using the specified source ID.  A stream can only be played if it is not already playing.
' You must call alureUpdate at regular intervals to keep the stream playing, or else the stream will underrun
' and cause a break in the playback until an update call can restart it.
' If an underrun occurs, the source will enter a stopped state until it is automatically restarted.  Instead, set a flag using the callback to indicate the stream being stopped.
' "eos_callback": This callback will be called when the stream reaches the end, no more loops are pending, and the source reaches a stopped state.
' It will also be called if an error occured and playback terminated.
' Returns: AL_FALSE On error.
Private Extern alurePlaySourceStream(source As Integer, strePnt As Pointer, numBufs As Integer, loopcount As Integer, eos_callback As Pointer, userdata As Pointer) As Boolean

' ALboolean alureSetStreamPatchset(alureStream * stream, Const ALchar * patchset)
' Specifies the patchset to use for MIDI streams.  By default, the FluidSynth decoder will look for one in the FLUID_SOUNDFONT environment variable,
' but this can be used to change it to something different.  On non-MIDI streams, this has no effect.
' Returns: AL_FALSE On error.
Private Extern alureSetStreamPatchset(strePnt As Pointer, patchset As String) As Boolean

' void alureUpdate(void)
' Updates the running list of streams, and checks for stopped sources.
' This makes sure that sources played with alurePlaySourceStream are kept fed from their associated stream, and sources played with alurePlaySource are still playing.
' It will call their callbacks as needed.
Private Extern alureUpdate()

' ALboolean alureStopSource(ALuint source, ALboolean run_callback)
' Stops the specified source ID, and any associated stream.
' Returns: AL_FALSE On error.
Private Extern alureStopSource(source As Integer, run_callback As Boolean) As Boolean

' void alDeleteSources(ALsizei n, ALuint * sources)
' This function deletes one or more sources.
Private Extern alDeleteSources(n As Integer, sources As Pointer) In "libalut:0.1.0"

' ALboolean alureDestroyStream(alureStream * stream, ALsizei numBufs, ALuint * bufs)'
' Closes an opened stream.
' Returns: AL_FALSE On error.
Private Extern alureDestroyStream(strePnt As Pointer, numBufs As Integer, bufs As Pointer) As Boolean

' ALboolean alureShutdownDevice(void)
' Destroys the current context and closes its associated device.
' Returns: AL_FALSE On error.
Private Extern alureShutdownDevice() As Boolean

' ALboolean alurePauseSource(ALuint source)
' Pauses the specified source ID, and any associated stream. Returns AL_FALSE On Error.
Private Extern alurePauseSource(source As Integer) As Boolean

' ALboolean alureResumeSource(ALuint source)
' Resumes the specified source ID after being paused. Returns AL_FALSE On Error.
Private Extern alureResumeSource(source As Integer) As Boolean


' void exit(int status)
' Terminates the calling process immediately.
Private Extern C_exit(status As Integer) In "libc:6" Exec "exit"
 

Public Sub Button1_Click()

  Dim ver As Boolean
  Dim percorsoFile As String = "/percorso/del/file.mid"
  Dim lungh As Integer
  Dim tm As Date
  
  ver = alureInitDevice(Null, Null)
  If ver = False Then Error.Raise("Impossibile inizializzare la libreria 'Alure' !")
  
  alGenSources(1, VarPtr(src))
 
  lungh = Stat(percorsoFile).Size
 
' Se si preferisce impostare la durata in base alla dimensione del file  da eseguire,
' è opportuno passare il valore del secondo parametro almeno pari alla dimensione del file:
  streamP = alureCreateStreamFromFile(percorsoFile, lungh, 0, Null)
  If streamP == 0 Then Error.Raise("Impossibile caricare il file Midi !")
 
  ver = alureSetStreamPatchset(streamP, "/percorso/del/file/soundfont.sf2")
  If ver = False Then Error.Raise("Impossibile impostare il file del banco-suoni !")

' Il terzo parametro della seguente 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 Midi deve essere di almeno 2.
  ver = alurePlaySourceStream(src, streamP, 3, 0, eos_callback, Null)
  If ver = False Then Error.Raise("Impossibile eseguire il flusso dati audio !")

  tm = Now

  While isdone == 0
    Write "\r\e[0mTempo trascorso: \e[31m" & Str(Time(0, 0, 0, DateDiff(tm, Now, gb.Millisecond)))
    Wait 0.01
    alureUpdate()
  Wend
  
' Va in chiusura:
  AlureStop()
  isdone = 0
  
End

Private Function eos_callback(unused As Pointer, unused2 As Integer)

   isdone = 1
 
End

' Mette in pausa l'esecuzione:
Public Sub Button2_Click()

  alurePauseSource(src)

End

' Riprende l'esecuzione:
Public Sub Button3_Click()

  alureResumeSource(src)

End

' Arresta l'esecuzione:
Public Sub Button4_Click()

  AlureStop()

End

' Arresta l'esecuzione e chiude la finestra del programma:
Public Sub Button5_Click()
 
 AlureStop()

 Me.Close
 C_exit(0)
 
End

Private Procedure AlureStop()

 alureStopSource(src, False)
 alDeleteSources(1, VarPtr(src))
 alureDestroyStream(streamP, 0, Null)
 alureShutdownDevice()

End


Riferimenti