Generare un'onda sinusoidale con le funzioni esterne della libreria PortAudio
Da Gambas-it.org - Wikipedia.
Versione del 14 lug 2014 alle 05:24 di Vuott (Discussione | contributi)
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:
Public Struct PaStreamParameters device As Integer channelCount As Integer sampleFormat As Long suggestedLatency As Float hostApiSpecificStreamInfo As Pointer End Struct Private Const SAMPLE_RATE As Integer = 44100 Private Const FRAMES_PER_BUFFER As Integer = 1024 Private Const FREQUENZA As Short = 440 Private Const paNoError As Integer = 0 Private Const paNoDevice As Integer = -1 Private Const paFloat32 As Integer = 1 Private Const paClipOff As Integer = 1 Library "libportaudio:2.0.0" ' 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 As Integer Dim buffer As New Single[1024, 2] ' Buffer per Uscita stereo Dim sinus As New Single[FREQUENZA] ' Frequenza dell'onda sinusoidale Dim inc_sin As Integer = 2 Dim inc_des As Integer = 2 For i = 0 To FREQUENZA - 1 sinus[i] = CSingle(Sin((CFloat(i) / CFloat(FREQUENZA)) * 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 ' Uscita a 32 bit 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 >= FREQUENZA Then fase_sin -= FREQUENZA fase_des += inc_des If fase_des >= FREQUENZA Then fase_des -= FREQUENZA Next err = Pa_WriteStream(PaStream, buffer, FRAMES_PER_BUFFER) If err < paNoError Then Error.Raise("Impossibile avviare il processo audio: " & Pa_GetErrorText(err)) 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