diff options
| author | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-06-16 20:51:36 +0000 |
|---|---|---|
| committer | SND\edgbla_cp <SND\edgbla_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2011-06-16 20:51:36 +0000 |
| commit | 2b719752cd6e896e104e68cc67e34e59131f8fba (patch) | |
| tree | 858be7737e4b61cfe858f6f53007813bc3a2860b /plugins | |
| parent | de7058e26c5dc28ffeb0ecdcfd2a475217fa92d0 (diff) | |
| download | pcsxr-2b719752cd6e896e104e68cc67e34e59131f8fba.tar.gz | |
dfsound, openal.
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@67915 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/dfsound/Makefile.am | 6 | ||||
| -rwxr-xr-x | plugins/dfsound/openal.c | 307 | ||||
| -rw-r--r-- | plugins/dfsound/spu.c | 2 |
3 files changed, 315 insertions, 0 deletions
diff --git a/plugins/dfsound/Makefile.am b/plugins/dfsound/Makefile.am index 54ee4315..b47d501b 100644 --- a/plugins/dfsound/Makefile.am +++ b/plugins/dfsound/Makefile.am @@ -34,6 +34,12 @@ libDFSound_la_CPPFLAGS += -DUSESDL=1 $(SDL_CFLAGS) libDFSound_la_LIBADD += $(SDL_LIBS)
endif
+if SOUND_OPENAL
+libDFSound_la_SOURCES += openal.c
+libDFSound_la_CPPFLAGS += -DUSEOPENAL=1
+libDFSound_la_LIBADD += $(OPENAL_LIBS)
+endif
+
if SOUND_NULL
libDFSound_la_SOURCES += nullsnd.c
libDFSound_la_CPPFLAGS += -DUSENULL=1
diff --git a/plugins/dfsound/openal.c b/plugins/dfsound/openal.c new file mode 100755 index 00000000..5262b732 --- /dev/null +++ b/plugins/dfsound/openal.c @@ -0,0 +1,307 @@ +/***************************************************************************
+ * Copyright (C) 2011 by Blade_Arma *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. *
+ ***************************************************************************/
+
+#include "stdafx.h"
+
+#define _IN_OSS
+
+#include "externals.h"
+
+#include <AL/al.h>
+#include <AL/alc.h>
+
+/******************************************************************************/
+/* Defines.
+ */
+
+#define BUFFER_SIZE_TOTAL (32768)
+#define BUFFER_SIZE (2048)
+#define BUFFER_QUANTITY (BUFFER_SIZE_TOTAL / BUFFER_SIZE)
+
+/******************************************************************************/
+/* Variables.
+ */
+
+static ALCdevice *pDevice;
+static ALCcontext *pContext;
+
+// Buffers hold sound data.
+static ALuint buffers[BUFFER_QUANTITY];
+
+// Sources are points emitting sound.
+static ALuint source;
+
+// Position of the source sound.
+static ALfloat SourcePos[] = {0.0, 0.0, 0.0};
+
+// Velocity of the source sound.
+static ALfloat SourceVel[] = {0.0, 0.0, 0.0};
+
+// Direction of the source sound.
+static ALfloat SourceDir[] = {0.0, 0.0, 0.0};
+
+// Position of the listener.
+static ALfloat ListenerPos[] = {0.0, 0.0, 0.0};
+
+// Velocity of the listener.
+static ALfloat ListenerVel[] = {0.0, 0.0, 0.0};
+
+// Orientation of the listener. (first 3 elements are "at", second 3 are "up")
+static ALfloat ListenerOri[] = {0.0, 0.0, -1.0, 0.0, 1.0, 0.0};
+
+static ALenum format = AL_FORMAT_STEREO16;
+static ALuint sampleRate = 44100;
+static ALuint sampleQuality = 16;
+static ALuint channels = 2;
+
+/******************************************************************************/
+/* Error handling.
+ */
+
+char* GetALErrorString(ALenum error)
+{
+ switch(error)
+ {
+ case AL_NO_ERROR:
+ return 0;
+ case AL_INVALID_NAME:
+ return "AL_INVALID_NAME";
+ case AL_INVALID_ENUM:
+ return "AL_INVALID_ENUM";
+ case AL_INVALID_VALUE:
+ return "AL_INVALID_VALUE";
+ case AL_INVALID_OPERATION:
+ return "AL_INVALID_OPERATION";
+ case AL_OUT_OF_MEMORY:
+ return "AL_OUT_OF_MEMORY";
+ };
+
+ return "AL_UNKNOWN_ERROR";
+}
+
+char* GetALCErrorString(ALenum error)
+{
+ switch(error)
+ {
+ case ALC_NO_ERROR:
+ return 0;
+ case ALC_INVALID_DEVICE:
+ return "ALC_INVALID_DEVICE";
+ case ALC_INVALID_CONTEXT:
+ return "ALC_INVALID_CONTEXT";
+ case ALC_INVALID_ENUM:
+ return "ALC_INVALID_ENUM";
+ case ALC_INVALID_VALUE:
+ return "ALC_INVALID_VALUE";
+ case ALC_OUT_OF_MEMORY:
+ return "ALC_OUT_OF_MEMORY";
+ };
+
+ return "ALC_UNKNOWN_ERROR";
+}
+
+int checkALError()
+{
+ char *pErrorString = GetALErrorString(alGetError());
+ if(pErrorString)
+ {
+ fprintf(stderr, "[SPU] AL: %s.\n", pErrorString);
+ return -1;
+ }
+
+ return 0;
+}
+
+int checkALCError()
+{
+ char *pErrorString = GetALCErrorString(alcGetError(pDevice));
+ if(pErrorString)
+ {
+ fprintf(stderr, "[SPU] ALC: %s.\n", pErrorString);
+ return -1;
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+
+void SetupSound()
+{
+ unsigned char buf[BUFFER_SIZE];
+ int i;
+
+ // Get handle to device.
+ pDevice = alcOpenDevice(NULL);
+ if(checkALCError())
+ {
+ fprintf(stderr, "[SPU] alcOpenDevice failed.\n");
+ return;
+ }
+
+ // ALC info.
+ const ALCubyte* deviceName = (ALCubyte*)alcGetString(pDevice, ALC_DEVICE_SPECIFIER);
+ //printf("[SPU] ALC_DEVICE_SPECIFIER = %s.\n", deviceName);
+
+ const ALCubyte* extensionList = (ALCubyte*)alcGetString(pDevice, ALC_EXTENSIONS);
+ //printf("[SPU] ALC_EXTENSIONS = %s.\n", extensionList);
+
+ // Create audio context.
+ pContext = alcCreateContext(pDevice, NULL);
+ if(checkALCError())
+ {
+ fprintf(stderr, "[SPU] alcCreateContext failed.\n");
+ return;
+ }
+
+ // Set active context.
+ alcMakeContextCurrent( pContext );
+ if( checkALCError() )
+ {
+ fprintf(stderr, "[SPU] alcMakeContextCurrent failed.\n");
+ return;
+ }
+
+ // AL info.
+ const ALubyte* version = (ALubyte*)alGetString(AL_VERSION);
+ //printf("[SPU] AL_VERSION = %s.\n", version);
+
+ const ALubyte* renderer = (ALubyte*)alGetString(AL_RENDERER);
+ //printf("[SPU] AL_RENDERER = %s.\n", renderer);
+
+ const ALubyte* vendor = (ALubyte*)alGetString(AL_VENDOR);
+ //printf("[SPU] AL_VENDOR = %s.\n", vendor);
+
+ // Create buffers.
+ alGenBuffers(BUFFER_QUANTITY, buffers);
+ checkALError();
+
+ // Load sound data into a buffer.
+ memset(buf, 0x00, BUFFER_SIZE);
+ for(i = 0; i < BUFFER_QUANTITY; ++i)
+ {
+ alBufferData(buffers[i], format, buf, BUFFER_SIZE, sampleRate);
+ }
+ checkALError();
+
+ // Create source.
+ alGenSources(1, &source);
+ checkALError();
+
+ // Bind buffer with a source.
+ alSourcef (source, AL_PITCH, 1.0f );
+ alSourcef (source, AL_GAIN, 1.0f );
+ alSourcefv(source, AL_POSITION, SourcePos);
+ alSourcefv(source, AL_VELOCITY, SourceVel);
+ alSourcefv(source, AL_DIRECTION, SourceDir);
+ alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE );
+ alSourcei (source, AL_LOOPING, AL_FALSE );
+
+ // Listener properties.
+ alListenerfv(AL_POSITION, ListenerPos);
+ alListenerfv(AL_VELOCITY, ListenerVel);
+ alListenerfv(AL_ORIENTATION, ListenerOri);
+
+ // Add buffers to queue.
+ alSourceQueueBuffers(source, BUFFER_QUANTITY, buffers);
+ checkALError();
+
+ // Enable playing.
+ alSourcePlay(source);
+ checkALError();
+}
+
+void RemoveSound()
+{
+ alSourceStop(source);
+ checkALError();
+ alDeleteSources(1, &source);
+ checkALError();
+ alDeleteBuffers(BUFFER_QUANTITY, buffers);
+ checkALError();
+
+ // Reset the current context to NULL.
+ alcMakeContextCurrent(NULL);
+ checkALCError();
+
+ // RELEASE the context and the device.
+ alcDestroyContext(pContext);
+ checkALCError();
+ alcCloseDevice(pDevice);
+}
+
+/******************************************************************************/
+
+unsigned long SoundGetBytesBuffered()
+{
+ ALint processed;
+ int buffered;
+
+ alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+ checkALError();
+
+ buffered = BUFFER_SIZE_TOTAL - processed * BUFFER_SIZE;
+ //printf("[SPU] SoundGetBytesBuffered: %i\n", buffered);
+
+ return buffered;
+}
+
+/******************************************************************************/
+
+void SoundFeedStreamData(unsigned char *pData, long lBytes)
+{
+ ALint processed;
+ ALint state;
+ ALuint buffer;
+ int needed;
+ int i;
+
+ //printf("[SPU] SoundFeedStreamData: %i\n", lBytes);
+
+ needed = (lBytes + (BUFFER_SIZE - 1)) / BUFFER_SIZE;
+
+ // Expect free buffer.
+ alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+ while(processed < needed)
+ {
+ usleep(1);
+ alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+ }
+
+ // Add buffers to queue.
+ for(i = 0; i < needed; ++i)
+ {
+ alSourceUnqueueBuffers(source, 1, &buffer);
+ alBufferData(buffer, format, pData, lBytes > BUFFER_SIZE ? BUFFER_SIZE : lBytes, sampleRate);
+ alSourceQueueBuffers(source, 1, &buffer);
+ lBytes -= BUFFER_SIZE;
+ pData += BUFFER_SIZE;
+ }
+
+ // Restart playing.
+ alGetSourcei(source, AL_SOURCE_STATE, &state);
+ if(state != AL_PLAYING)
+ {
+ //fprintf(stderr, "[SPU] AL_SOURCE_STATE != AL_PLAYING: %x\n", state);
+ alSourcePlay(source);
+ checkALError();
+ }
+}
+
+/******************************************************************************/
diff --git a/plugins/dfsound/spu.c b/plugins/dfsound/spu.c index d009692b..8d9b0ea3 100644 --- a/plugins/dfsound/spu.c +++ b/plugins/dfsound/spu.c @@ -49,6 +49,8 @@ static char * libraryName = N_("ALSA Sound"); static char * libraryName = N_("OSS Sound");
#elif defined (USESDL)
static char * libraryName = N_("SDL Sound");
+#elif defined (USEOPENAL)
+static char * libraryName = N_("OpenAL Sound");
#elif defined (USEPULSEAUDIO)
static char * libraryName = N_("PulseAudio Sound");
#else
|
