Eseguire un file WAVE mediante le funzioni delle librerie libopenal e libaudio
Da Gambas-it.org - Wikipedia.
Mostreremo in questa pagina un esempio per eseguire file di formato WAV, utilizzando la libreria standard di OpenAl e la libreria Libaudio.
Per poter fruire in Gambas delle risorse esterne delle predette librerie, bisognerà richiamare le librerie condivise: "libopenal.so.1.24.1 " e "libaudio.so.2.4 ".
Di seguito un possibile codice:
Library "libopenal:1.24.1" Private Const AL_POSITION As Integer = &1004 Private Const AL_VELOCITY As Integer = &1006 Private Const AL_ORIENTATION As Integer = &100F Private Const AL_PITCH As Integer = &1003 Private Const AL_GAIN As Integer = &100A Private Const AL_LOOPING As Integer = &1007 Private Const AL_FALSE As Integer = 0 Private Const AL_BUFFER As Integer = &1009 Private Const AL_SOURCE_STATE As Integer = &1010 Private Const AL_PLAYING As Integer = &1012 Private Const AL_FORMAT_STEREO8 As Integer = &1102 Private Const AL_FORMAT_MONO8 As Integer = &1100 Private Const AL_FORMAT_STEREO16 As Integer = &1103 Private Const AL_FORMAT_MONO16 As Integer = &1101 ' ALCdevice *alcOpenDevice(const ALCchar *devicename) ' Initialize the OpenAL audio layer. Returns a pointer to the opened device. Private Extern alcOpenDevice(devicename As String) As Pointer ' ALCcontext * alcCreateContext(ALCdevice *device, ALCint* attrlist) ' Creates a context using a specified device. Private Extern alcCreateContext(dev As Pointer, attrlist As Pointer) As Pointer ' ALCboolean alcMakeContextCurrent(ALCcontext *context) ' Makes a specified context the current context. Private Extern alcMakeContextCurrent(contexP As Pointer) ' ALenum alGetError(ALvoid) ' Returns the current error state and then clears the Error state. Private Extern alGetError() As Integer ' Alvoid alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) ' Sets a floating point property for the listener. Private Extern alListener3f(param As Integer, value1 As Single, value2 As Single, value3 As Single) ' Alvoid alListenerfv(ALenum param, const ALfloat *values) ' Sets a floating point-vector property of the listener. Private Extern alListenerfv(param As Integer, values As Single[]) ' Alvoid alGenSources(Alsizei n, ALuint *sources) ' Create Source objects. Private Extern alGenSources(n As Integer, sources As Pointer) ' Alvoid alSourcef(ALuint source, ALenum param, ALfloat value) ' Sets a floating point property of a source. Private Extern alSourcef(source As Integer, param As Integer, Alvalue As Single) ' Alvoid alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) ' Sets a source property requiring three floating point values. Private Extern alSource3f(source As Integer, param As Integer, value1 As Single, value2 As Single, value3 As Single) ' Alvoid alSourcei(ALuint source, ALenum param, ALint value) ' Sets an integer Property of a source. Private Extern alSourcei(source As Integer, param As Integer, Alint As Integer) ' void alGenBuffers(ALsizei n, ALuint * sources) ' Create Buffer objects. Private Extern alGenBuffers(n As Integer, buffers As Pointer) ' void alBufferData(ALuint buffer, ALenum Format, Const ALvoid * data, ALsizei size, ALsizei freq) ' Fills a buffer with audio data. Private Extern alBufferData(buffer As Integer, formato As Integer, data As Pointer, size As Integer, freq As Integer) ' void alSourcePlay(ALuint source) ' Plays a source. The playing source will have its state changed To AL_PLAYING. Private Extern alSourcePlay(sourcI As Integer) ' void alGetSourcei(ALuint source, ALenum pname, ALint * value) ' Retrieves an integer property of a source. Private Extern alGetSourcei(sourcI As Integer, PNAME As Integer, valP As Pointer) ' void alDeleteSources(ALsizei n, const ALuint * sources) ' Delete Source objects. Private Extern alDeleteSources(n As Integer, sources As Pointer) ' void alDeleteBuffers(ALsizei n, const ALuint * buffers) ' Delete Buffer objects. Private Extern alDeleteBuffers(n As Integer, buffers As Pointer) ' void alcDestroyContext(ALCcontext context) ' Destroy an OpenAl context. Private Extern alcDestroyContext(contexP As Pointer) ' ALCboolean alcCloseDevice (ALCdevice *Device) ' Allows the application (i.e. the client program) to disconnect from a device (i.e. the server). Private Extern alcCloseDevice(dev As Pointer) Library "libaudio:2.4" Public Struct WaveInfo fp As Pointer comment As Pointer channels As Short bitsPerSample As Short sampleRate As Integer dataOffset As Integer numSamples As Integer fileSize As Integer dataSize As Integer sizeOffset As Integer writing As Integer formatSh As Short End Struct ' WaveInfo * WaveOpenFileForReading(const char *name) ' Open an wave file for reading. Private Extern WaveOpenFileForReading(name As String) As WaveInfo ' int WaveSeekFile(int n, WaveInfo *wi) ' Seek to a position in an wave file. Private Extern WaveSeekFile(n As Integer, wi As WaveInfo) As Integer ' int WaveReadFile(char *p, int n, WaveInfo *wi) ' Read wave data from an audio file. Private Extern WaveReadFile(p As Pointer, n As Integer, wi As WaveInfo) As Integer ' int WaveCloseFile(WaveInfo *wi) ' Close an wave file description. Private Extern WaveCloseFile(wi As WaveInfo) As Integer Public Sub Main() Dim device, context, data As Pointer Dim fileWav As String Dim err, Alsource, buffer, bit, status As Integer Dim orient As Single[] = [0.0, 0.0, 1.0, 0.0, 1.0, 0.0] Dim info As New WaveInfo fileWav = "/percorso/del/file.wav" device = alcOpenDevice("OpenAL Soft") If device == 0 Then Error.Raise("Errore !") ' Crea un contesto OpenAl: context = alcCreateContext(device, Null) ' Imposta un contesto attivo: alcMakeContextCurrent(context) err = alGetError() If err <> 0 Then Error.Raise("Errore nella inizializzazione della libreria !") ' Imposta l'orientazione: alListener3f(AL_POSITION, 0, 0, 1.0) alListener3f(AL_VELOCITY, 0, 0, 0) alListenerfv(AL_ORIENTATION, orient) ' Genera il sorgente audio: alGenSources(1, VarPtr(Alsource)) alSourcef(Alsource, AL_PITCH, 1) alSourcef(Alsource, AL_GAIN, 1) alSource3f(Alsource, AL_POSITION, 0, 0, 0) alSource3f(Alsource, AL_VELOCITY, 0, 0, 0) alSourcei(Alsource, AL_LOOPING, AL_FALSE) ' Genera il buffer audio: alGenBuffers(1, VarPtr(buffer)) ' ' ' ' ' Libaudio ' ' ' ' ' ' info = WaveOpenFileForReading(fileWav) If IsNull(info) Then Error.Raise("Errore nella lettura del file wav !") err = WaveSeekFile(0, info) If err Then Error.Raise("Impossibile posizionarsi nel file wav !") data = Alloc(info.dataSize) If data == 0 Then Error.Raise("Impossibile allocare memoria !") err = WaveReadFile(data, info.dataSize, info) If err <> info.dataSize Then Error.Raise("Dati insufficienti:", err, "voleva: ", info.dataSize) ' ' ' ' ' ' ' bit = FormatoBit(info.channels, info.bitsPerSample) alBufferData(buffer, bit, data, info.dataSize, info.sampleRate) alSourcei(Alsource, AL_BUFFER, buffer) ' Esegue il sorgente audio: alSourcePlay(Alsource) ' Ottiene lo stato del sorgente audio: alGetSourcei(Alsource, AL_SOURCE_STATE, VarPtr(status)) While status = AL_PLAYING alGetSourcei(Alsource, AL_SOURCE_STATE, VarPtr(status)) Wend ' Va in chiusura: WaveCloseFile(info) Free(data) alDeleteSources(1, VarPtr(Alsource)) alDeleteBuffers(1, VarPtr(buffer)) alcMakeContextCurrent(Null) alcDestroyContext(context) alcCloseDevice(device) End Private Function FormatoBit(canali As Short, bitxcamp As Short) As Integer Dim rit As Integer Select bitxcamp Case 8 If canali > 1 Then rit = AL_FORMAT_STEREO8 Else rit = AL_FORMAT_MONO8 Endif Case 16 If canali > 1 Then rit = AL_FORMAT_STEREO16 Else rit = AL_FORMAT_MONO16 Endif End Select Return rit End