Differenze tra le versioni di "Generare un'onda sinusoidale con le funzioni esterne della libreria PortAudio"

Da Gambas-it.org - Wikipedia.
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 1: Riga 1:
 
La libreria '''PortAudio''' è una libreria per la gestione in tempo reale dei dati audio in entrata ed in uscita. Essa fa parte di un assortimento di API e librerie create per la musica e per altri media.
 
La libreria '''PortAudio''' è una libreria per la gestione in tempo reale dei dati audio in entrata ed in uscita. Essa fa parte di un assortimento di API e librerie create per la musica e per altri media.
  
E' possibile con alcune funzioni esterne della libreria ''PortAudio'' generare un'onda sinusoidale. Sarà necessario avere installata nel proprio sistema la libreria condivisa: ''libportaudio.so.2.0.0
+
E' possibile con alcune funzioni esterne della libreria ''PortAudio'' generare un'onda sinusoidale. Sarà necessario avere installata nel proprio sistema la libreria condivisa: "''libportaudio.so.2.0.0'' ".
  
  
Mostriamo di seguito un possibile codice (per variare la frequenza dell'onda sinusoidale bisognerà modificare i valori della costante ''TABLE_SIZE'' e delle variabili ''inc_sin'' ed ''inc_des''):
+
Mostriamo di seguito un possibile codice (per variare la frequenza dell'onda sinusoidale bisognerà modificare i valori della Costante ''TABLE_SIZE'' e delle variabili ''inc_sin'' ed ''inc_des''):
 +
Private Const TABLE_SIZE As Short = <FONT Color=#B22222>440</font>
 +
Private Const SAMPLE_RATE As Integer = 44100
 +
Private Const FRAMES_PER_BUFFER As Integer = 1024
 +
 +
Library "libportaudio:2.0.0"
 +
 
  Public Struct PaStreamParameters
 
  Public Struct PaStreamParameters
 
   device As Integer
 
   device As Integer
Riga 13: Riga 19:
 
  End Struct
 
  End Struct
 
   
 
   
Private Const SAMPLE_RATE As Integer = 44100
 
Private Const FRAMES_PER_BUFFER As Integer = 1024
 
Private Const TABLE_SIZE As Short = 440
 
 
  Private Const paNoError As Integer = 0
 
  Private Const paNoError As Integer = 0
 
  Private Const paNoDevice As Integer = -1
 
  Private Const paNoDevice As Integer = -1
 
  Private Const paFloat32 As Integer = 1
 
  Private Const paFloat32 As Integer = 1
 
  Private Const paClipOff As Integer = 1
 
  Private Const paClipOff As Integer = 1
 
 
 
Library "libportaudio:2.0.0"
 
 
   
 
   
 
  <FONT color=gray>' ''PaError Pa_Initialize(void)''
 
  <FONT color=gray>' ''PaError Pa_Initialize(void)''
Riga 68: Riga 68:
 
   Dim inc_sin As Byte = 4
 
   Dim inc_sin As Byte = 4
 
   Dim inc_des As Byte = 4
 
   Dim inc_des As Byte = 4
 
 
 
   
 
   
  For i = 0 To TABLE_SIZE - 1
+
  For i = 0 To TABLE_SIZE - 1
    sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
+
    sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
  Next
+
  Next
 
      
 
      
  err = Pa_Initialize()
+
  err = Pa_Initialize()
  If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))
+
  If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))
 
    
 
    
  outputParameters.device = Pa_GetDefaultOutputDevice()    <FONT color=gray>' ''Dispositivo audio prestabilito''</font>
+
  outputParameters.device = Pa_GetDefaultOutputDevice()    <FONT color=gray>' ''Dispositivo audio prestabilito''</font>
  If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
+
  If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
  outputParameters.channelCount = 2                        <FONT color=gray>' ''Uscita stereo''</font>
+
  outputParameters.channelCount = 2                        <FONT color=gray>' ''Uscita stereo''</font>
  outputParameters.sampleFormat = paFloat32
+
  outputParameters.sampleFormat = paFloat32
  outputParameters.suggestedLatency = 0.050
+
  outputParameters.suggestedLatency = 0.050
  outputParameters.hostApiSpecificStreamInfo = Null
+
  outputParameters.hostApiSpecificStreamInfo = Null
 
      
 
      
  err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
+
  err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
  If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
+
  If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
 
      
 
      
  err = Pa_StartStream(PaStream)
+
  err = Pa_StartStream(PaStream)
  If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
+
  If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
   
+
 
+
  For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
  For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
+
    For j = 0 To FRAMES_PER_BUFFER - 1
    For j = 0 To FRAMES_PER_BUFFER - 1
+
      buffer[j, 1] = sinus[fase_sin]          <FONT color=gray>' ''Canale sinistro''</font>
      buffer[j, 1] = sinus[fase_sin]          <FONT color=gray>' ''Canale sinistro''</font>
+
      buffer[j, 0] = sinus[fase_des]          <FONT color=gray>' ''Canale destro''</font>
      buffer[j, 0] = sinus[fase_des]          <FONT color=gray>' ''Canale destro''</font>
+
      fase_sin += inc_sin
      fase_sin += inc_sin
+
      If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
      If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
+
      fase_des += inc_des
      fase_des += inc_des
+
      If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
      If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
+
    Next
    Next
+
    err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER)
    err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER)
+
    If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
    If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
 
   
 
 
  <FONT color=gray>' ''Mostra il tempo trascorso dall'inizio dell'esecuzione dell'onda sonora:''</font>
 
  <FONT color=gray>' ''Mostra il tempo trascorso dall'inizio dell'esecuzione dell'onda sonora:''</font>
    somma += FRAMES_PER_BUFFER
+
    somma += FRAMES_PER_BUFFER
    Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / SAMPLE_RATE) * 1000)
+
    Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / SAMPLE_RATE) * 1000)
  Next
+
  Next
 
      
 
      
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  err = Pa_CloseStream(PaStream)
+
  err = Pa_CloseStream(PaStream)
  If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
+
  If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
 
      
 
      
  Pa_Terminate()
+
  Pa_Terminate()
 
   
 
   
 
  '''End'''
 
  '''End'''
 
+
ed una sua leggera variante (anche in questo codice per variare la frequenza prestabilita dell'onda sinusoidale bisognerà modificare i valori della Costante ''TABLE_SIZE'' e delle variabili ''inc_sin'' ed ''inc_des''):
 
+
Private Const TABLE_SIZE As Short = <FONT Color=#B22222>440</font>
ed una sua leggera variante (anche in questo codice per variare la frequenza prestabilita dell'onda sinusoidale bisognerà modificare i valori della costante ''TABLE_SIZE'' e delle variabili ''inc_sin'' ed ''inc_des''):
+
Private Const SAMPLE_RATE As Integer = 44100
 +
Private Const FRAMES_PER_BUFFER As Integer = 1024
 +
 +
Library "libportaudio:2.0.0"
 +
 
  Public Struct PaStreamParameters
 
  Public Struct PaStreamParameters
 
   device As Integer
 
   device As Integer
Riga 139: Riga 140:
 
  End Struct
 
  End Struct
 
   
 
   
Private Const SAMPLE_RATE As Integer = 44100
 
Private Const FRAMES_PER_BUFFER As Integer = 1024
 
Private Const TABLE_SIZE As Short = 440
 
 
  Private Const paNoError As Integer = 0
 
  Private Const paNoError As Integer = 0
 
  Private Const paNoDevice As Integer = -1
 
  Private Const paNoDevice As Integer = -1
 
  Private Const paFloat32 As Integer = 1
 
  Private Const paFloat32 As Integer = 1
 
  Private Const paClipOff As Integer = 1
 
  Private Const paClipOff As Integer = 1
 
 
 
Library "libportaudio:2.0.0"
 
 
   
 
   
 
  <FONT color=gray>' ''PaError Pa_Initialize(void)''
 
  <FONT color=gray>' ''PaError Pa_Initialize(void)''
Riga 194: Riga 189:
 
   Dim pdi As New PaDeviceInfo
 
   Dim pdi As New PaDeviceInfo
 
   Dim PaStream As Pointer
 
   Dim PaStream As Pointer
   Dim err, fase_sin, fase_des, i, j, k As Integer
+
   Dim err, fase_sin, fase_des, i, j, k, somma As Integer
 
   Dim buffer As New Single[FRAMES_PER_BUFFER]
 
   Dim buffer As New Single[FRAMES_PER_BUFFER]
 
   Dim sinus As New Single[TABLE_SIZE]
 
   Dim sinus As New Single[TABLE_SIZE]
 
   Dim inc_sin As Byte = 4
 
   Dim inc_sin As Byte = 4
 
   Dim inc_des As Byte = 4
 
   Dim inc_des As Byte = 4
 +
 +
  For i = 0 To TABLE_SIZE - 1
 +
    sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
 +
  Next
 
    
 
    
 +
  err = Pa_Initialize()
 +
  If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))
 
   
 
   
  For i = 0 To TABLE_SIZE - 1
+
   outputParameters.device = Pa_GetDefaultOutputDevice()    <FONT color=gray>' ''Dispositivo audio prestabilito''</font>
    sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
+
  If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
  Next
+
  outputParameters.channelCount = 2                        <FONT color=gray>' ''Uscita stereo''</font>
   
+
  outputParameters.sampleFormat = paFloat32
  err = Pa_Initialize()
+
  pdi = Pa_GetDeviceInfo(outputParameters.device)
  If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))
+
  outputParameters.suggestedLatency = pdi.defaultLowOutputLatency
    
+
  outputParameters.hostApiSpecificStreamInfo = Null
  outputParameters.device = Pa_GetDefaultOutputDevice()    <FONT color=gray>' ''Dispositivo audio prestabilito''</font>
+
 
  If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
+
  err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
  outputParameters.channelCount = 2                        <FONT color=gray>' ''Uscita stereo''</font>
+
  If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
  outputParameters.sampleFormat = paFloat32
+
 
  pdi = Pa_GetDeviceInfo(outputParameters.device)
+
  err = Pa_StartStream(PaStream)
  outputParameters.suggestedLatency = pdi.defaultLowOutputLatency
+
  If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
  outputParameters.hostApiSpecificStreamInfo = Null
+
 
   
+
  For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
  err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
+
    For j = 0 To FRAMES_PER_BUFFER - 1 Step 2
  If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
+
      buffer[j] = sinus[fase_sin]          <FONT color=gray>' ''Canale sinistro''</font>
   
+
      buffer[j + 1] = sinus[fase_des]      <FONT color=gray>' ''Canale destro''</font>
  err = Pa_StartStream(PaStream)
+
      fase_sin += inc_sin
  If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
+
      If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
   
+
      fase_des += inc_des
+
      If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
  For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
+
    Next
    For j = 0 To FRAMES_PER_BUFFER - 1 Step 2
+
    err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER \ 2)
      buffer[j] = sinus[fase_sin]          <FONT color=gray>' ''Canale sinistro''</font>
+
    If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
      buffer[j + 1] = sinus[fase_des]      <FONT color=gray>' ''Canale destro''</font>
+
 
      fase_sin += inc_sin
+
<FONT color=gray>' ''Mostra il tempo trascorso dall'inizio dell'esecuzione dell'onda sonora:''</font>
      If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
+
    somma += (FRAMES_PER_BUFFER \ 2)
      fase_des += inc_des
+
    Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / SAMPLE_RATE) * 1000)
      If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
+
  Next
    Next
 
    err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER / 2)
 
    If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
 
  Next
 
 
      
 
      
 
  <FONT color=gray>' ''Va in chiusura:''</font>
 
  <FONT color=gray>' ''Va in chiusura:''</font>
  err = Pa_CloseStream(PaStream)
+
  err = Pa_CloseStream(PaStream)
  If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
+
  If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
 
      
 
      
  Pa_Terminate()
+
  Pa_Terminate()
 
   
 
   
 
  '''End'''
 
  '''End'''
 +
  
  

Versione attuale delle 16:50, 10 dic 2021

La libreria PortAudio è una libreria per la gestione in tempo reale dei dati audio in entrata ed in uscita. Essa fa parte di un assortimento di API e librerie create per la musica e per altri media.

E' possibile con alcune funzioni esterne della libreria PortAudio generare un'onda sinusoidale. Sarà necessario avere installata nel proprio sistema la libreria condivisa: "libportaudio.so.2.0.0 ".


Mostriamo di seguito un possibile codice (per variare la frequenza dell'onda sinusoidale bisognerà modificare i valori della Costante TABLE_SIZE e delle variabili inc_sin ed inc_des):

Private Const TABLE_SIZE As Short = 440
Private Const SAMPLE_RATE As Integer = 44100
Private Const FRAMES_PER_BUFFER As Integer = 1024

Library "libportaudio:2.0.0"

Public Struct PaStreamParameters
  device As Integer
  channelCount As Integer
  sampleFormat As Long
  suggestedLatency As Float
  hostApiSpecificStreamInfo As Pointer
End Struct

Private Const paNoError As Integer = 0
Private Const paNoDevice As Integer = -1
Private Const paFloat32 As Integer = 1
Private Const paClipOff As Integer = 1

' PaError Pa_Initialize(void)
' Library initialization function - call this before using PortAudio.
' This function initializes internal data structures and prepares underlying host APIs for use.
Private Extern Pa_Initialize() As Integer

' PaDeviceIndex Pa_GetDefaultOutputDevice( void )
' Retrieve the index of the default output device.
Private Extern Pa_GetDefaultOutputDevice() As Integer

' PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters,
' double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData )
' Opens a stream for either input, output or both.
Private Extern Pa_OpenStream(PaStr As Pointer, inPa As PaStreamParameters, outPa As PaStreamParameters, sampleRate As Float, fraPBuf As Long, Flags As Long, Callb As Pointer, Data As Pointer) As Integer

' PaError Pa_StartStream( PaStream *stream )
' Commences audio processing.
Private Extern Pa_StartStream(PaStr As Pointer) As Integer

' PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames )
' Write samples to an output stream.
Private Extern Pa_WriteStream(PaStr As Pointer, buff As Single[], frames As Long) As Integer

' PaError Pa_CloseStream( PaStream *stream )
' Closes an audio stream.
Private Extern Pa_CloseStream(PaStr As Pointer) As Integer

' PaError Pa_Terminate( void )
' Library termination function.
Private Extern Pa_Terminate() As Integer

' const char *Pa_GetErrorText(PaError errnum)
' Translates the supplied PortAudio error number into a human readable message.
Private Extern Pa_GetErrorText(errnum As Integer) As String


Public Sub Main()

 Dim outputParameters As New PaStreamParameters
 Dim PaStream As Pointer
 Dim err, fase_sin, fase_des, i, j, k, somma As Integer
 Dim buffer As New Single[1024, 2]                 ' Buffer per Uscita stereo
 Dim sinus As New Single[TABLE_SIZE]               ' Dati dell'onda sinusoidale
 Dim inc_sin As Byte = 4
 Dim inc_des As Byte = 4

 For i = 0 To TABLE_SIZE - 1
   sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
 Next
   
 err = Pa_Initialize()
 If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))
 
 outputParameters.device = Pa_GetDefaultOutputDevice()     ' Dispositivo audio prestabilito
 If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
 outputParameters.channelCount = 2                         ' Uscita stereo
 outputParameters.sampleFormat = paFloat32
 outputParameters.suggestedLatency = 0.050
 outputParameters.hostApiSpecificStreamInfo = Null
   
 err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
 If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
   
 err = Pa_StartStream(PaStream)
 If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
 
 For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
   For j = 0 To FRAMES_PER_BUFFER - 1
     buffer[j, 1] = sinus[fase_sin]          ' Canale sinistro
     buffer[j, 0] = sinus[fase_des]          ' Canale destro
     fase_sin += inc_sin
     If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
     fase_des += inc_des
     If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
   Next
   err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER)
   If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
' Mostra il tempo trascorso dall'inizio dell'esecuzione dell'onda sonora:
   somma += FRAMES_PER_BUFFER
   Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / SAMPLE_RATE) * 1000)
 Next
   
' Va in chiusura:
 err = Pa_CloseStream(PaStream)
 If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
   
 Pa_Terminate()

End

ed una sua leggera variante (anche in questo codice per variare la frequenza prestabilita dell'onda sinusoidale bisognerà modificare i valori della Costante TABLE_SIZE e delle variabili inc_sin ed inc_des):

Private Const TABLE_SIZE As Short = 440
Private Const SAMPLE_RATE As Integer = 44100
Private Const FRAMES_PER_BUFFER As Integer = 1024

Library "libportaudio:2.0.0"

Public Struct PaStreamParameters
  device As Integer
  channelCount As Integer
  sampleFormat As Long
  suggestedLatency As Float
  hostApiSpecificStreamInfo As Pointer
End Struct

Public Struct PaDeviceInfo
  structVersion As Integer
  name As Pointer
  hostApi As Integer
  maxInputChannels As Integer
  maxOutputChannels As Integer
  defaultLowInputLatency As Float
  defaultLowOutputLatency As Float
  defaultHighInputLatency As Float
  defaultHighOutputLatency As Float
  defaultSampleRate As Float
End Struct

Private Const paNoError As Integer = 0
Private Const paNoDevice As Integer = -1
Private Const paFloat32 As Integer = 1
Private Const paClipOff As Integer = 1

' PaError Pa_Initialize(void)
' Library initialization function - call this before using PortAudio.
' This function initializes internal data structures and prepares underlying host APIs for use.
Private Extern Pa_Initialize() As Integer

' PaDeviceIndex Pa_GetDefaultOutputDevice( void )
' Retrieve the index of the default output device.
Private Extern Pa_GetDefaultOutputDevice() As Integer

' const PaDeviceInfo * Pa_GetDeviceInfo(PaDeviceIndex device)
' Retrieve a pointer to a PaDeviceInfo structure containing information about the specified device.
Private Extern Pa_GetDeviceInfo(device As Integer) As PaDeviceInfo

' PaError Pa_OpenStream( PaStream** stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters,
' double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback *streamCallback, void *userData )
' Opens a stream for either input, output or both.
Private Extern Pa_OpenStream(PaStr As Pointer, inPa As PaStreamParameters, outPa As PaStreamParameters, sampleRate As Float, fraPBuf As Long, Flags As Long, Callb As Pointer, Data As Pointer) As Integer

' PaError Pa_StartStream( PaStream *stream )
' Commences audio processing.
Private Extern Pa_StartStream(PaStr As Pointer) As Integer

' PaError Pa_WriteStream( PaStream* stream, const void *buffer, unsigned long frames )
' Write samples to an output stream.
Private Extern Pa_WriteStream(PaStr As Pointer, buff As Single[], frames As Long) As Integer

' PaError Pa_CloseStream( PaStream *stream )
' Closes an audio stream.
Private Extern Pa_CloseStream(PaStr As Pointer) As Integer

' PaError Pa_Terminate( void )
' Library termination function.
Private Extern Pa_Terminate() As Integer

' const char *Pa_GetErrorText(PaError errnum)
' Translates the supplied PortAudio error number into a human readable message.
Private Extern Pa_GetErrorText(errnum As Integer) As String


Public Sub Main()

 Dim outputParameters As New PaStreamParameters
 Dim pdi As New PaDeviceInfo
 Dim PaStream As Pointer
 Dim err, fase_sin, fase_des, i, j, k, somma As Integer
 Dim buffer As New Single[FRAMES_PER_BUFFER]
 Dim sinus As New Single[TABLE_SIZE]
 Dim inc_sin As Byte = 4
 Dim inc_des As Byte = 4

 For i = 0 To TABLE_SIZE - 1
   sinus[i] = CSingle(Sin((CFloat(i) / CFloat(TABLE_SIZE)) * Pi * 2.0))
 Next
  
 err = Pa_Initialize()
 If err < paNoError Then Error.Raise("Impossibile inizializzare la libreria 'PortAudio': " & Pa_GetErrorText(err))

 outputParameters.device = Pa_GetDefaultOutputDevice()     ' Dispositivo audio prestabilito
 If outputParameters.device = paNoDevice Then Error.Raise("Nessun dispositvo audio presente nel sistema !")
 outputParameters.channelCount = 2                         ' Uscita stereo
 outputParameters.sampleFormat = paFloat32
 pdi = Pa_GetDeviceInfo(outputParameters.device)
 outputParameters.suggestedLatency = pdi.defaultLowOutputLatency
 outputParameters.hostApiSpecificStreamInfo = Null
  
 err = Pa_OpenStream(VarPtr(PaStream), Null, outputParameters, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, 0, 0)
 If err < paNoError Then Error.Raise("Impossibile aprire un flusso audio: " & Pa_GetErrorText(err))
  
 err = Pa_StartStream(PaStream)
 If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
 For k = 0 To ((10 * SAMPLE_RATE) / FRAMES_PER_BUFFER) - 1
   For j = 0 To FRAMES_PER_BUFFER - 1 Step 2
     buffer[j] = sinus[fase_sin]          ' Canale sinistro
     buffer[j + 1] = sinus[fase_des]      ' Canale destro
     fase_sin += inc_sin
     If fase_sin >= TABLE_SIZE Then fase_sin -= TABLE_SIZE
     fase_des += inc_des
     If fase_des >= TABLE_SIZE Then fase_des -= TABLE_SIZE
   Next
   err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER \ 2)
   If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err))
' Mostra il tempo trascorso dall'inizio dell'esecuzione dell'onda sonora:
   somma += (FRAMES_PER_BUFFER \ 2)
   Write #File.Out, "\rTempo trascorso: " & Date(0, 0, 0, 0, 0, 0, (somma / SAMPLE_RATE) * 1000)
 Next
   
' Va in chiusura:
 err = Pa_CloseStream(PaStream)
 If err < paNoError Then Error.Raise("Impossibile chiudere il flusso audio: " & Pa_GetErrorText(err))
   
 Pa_Terminate()

End


Riferimenti