Compare commits
191 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f72b6fe717 | |||
| 8d29d25d60 | |||
| af8e7ab984 | |||
| 4289d5de7d | |||
| 83734aff0e | |||
| 617b6728d3 | |||
| 7a8fd6cb20 | |||
| 55da339586 | |||
| 774eae0f2f | |||
| 201b108a54 | |||
| bdbdbcea26 | |||
| f6c1a21cf0 | |||
| c953072a15 | |||
| 93f3e9357b | |||
| 8ea8b49464 | |||
| 62cef44dcb | |||
| a2edc95207 | |||
| 4cd41e3e08 | |||
| b641f993ac | |||
| e2905b6bc9 | |||
| e11b59a80f | |||
| 0ae02e8ad4 | |||
| 2cbdffab86 | |||
| 86eefdb2a8 | |||
| 750399ccd7 | |||
| fb97ca6022 | |||
| cbcaa54173 | |||
| 94e3fca702 | |||
| ffff104554 | |||
| 307a9dd1b2 | |||
| 5dff8ea820 | |||
| 49648fe22d | |||
| 9f037e8980 | |||
| 12f81bcbb9 | |||
| 6636131d3b | |||
| eeea9631ce | |||
| f9d228c30a | |||
| d516f8c4bd | |||
| 5d1c3a0c63 | |||
| 396f2d6050 | |||
| e25b01c3a2 | |||
| b29a24afb0 | |||
| d6d1dba3d2 | |||
| 8b36a9d121 | |||
| 59ed9338d8 | |||
| b444dea63b | |||
| 1816c8bd37 | |||
| c27948a7ee | |||
| 832dc8a585 | |||
| bb121e68a6 | |||
| 1ec26fd789 | |||
| 4ff4a7e3b9 | |||
| 6bb14e45ce | |||
| 45dc804819 | |||
| 81db01ebf1 | |||
| 06c576a945 | |||
| 929b025fd6 | |||
| 7976de05a5 | |||
| 70c88879ab | |||
| 276ee63b99 | |||
| 487f0dde75 | |||
| c8f700930a | |||
| decbe4df45 | |||
| 462f27c129 | |||
| 2d1191697a | |||
| 0b5a0d1e79 | |||
| 0b7eb9f118 | |||
| dc26261065 | |||
| 9bea67fb1c | |||
| 8246bc3418 | |||
| 01e32b58da | |||
| 9d05ff0468 | |||
| 510ccc7f17 | |||
| 43067ed2b8 | |||
| 4e4c9aef15 | |||
| 4031ee5ef0 | |||
| e079291202 | |||
| 826c641668 | |||
| 6ae845fd9e | |||
| a78fd58dca | |||
| a8ae610489 | |||
| b86a1e5797 | |||
| 45552a68ce | |||
| d46655fbb2 | |||
| 87fee8c504 | |||
| 9ff0617807 | |||
| 243939f94f | |||
| 739385bd89 | |||
| 32060f53cd | |||
| 4ee3972f15 | |||
| 00a9cf4a85 | |||
| 1dcd538ad9 | |||
| a8973514ba | |||
| 0ac9e57d28 | |||
| 5460e85c40 | |||
| 432f0ba34c | |||
| 7e01e53445 | |||
| 043fe6edd2 | |||
| ef68e5d0ff | |||
| c6f3a4e062 | |||
| 87ed53c7f6 | |||
| 89e9437b84 | |||
| 1454c46b5f | |||
| 0fac1e9115 | |||
| f3a3358e63 | |||
| 3c122b0bef | |||
| 7940003d06 | |||
| 45b16ff456 | |||
| 9341f4f884 | |||
| 2c20f26784 | |||
| 2a21a449b4 | |||
| 74dc7090fd | |||
| e12ac95d69 | |||
| 34ea7eba9e | |||
| 6d3ba44f55 | |||
| 5a8ad67660 | |||
| f1e442408b | |||
| a946af4463 | |||
| e01cd92d56 | |||
| 923af8c3a6 | |||
| ac04cf57fa | |||
| 1f6c4e01db | |||
| 04135723a2 | |||
| 93fbdb1e6c | |||
| c1de15f840 | |||
| 3be399c555 | |||
| 1f5453075c | |||
| 33a74f1594 | |||
| e4da1224cb | |||
| 5c2a47620c | |||
| 1bfa7609d2 | |||
| 7e8501123a | |||
| c447eeb2c7 | |||
| ad19cea6e0 | |||
| 0ce29863e3 | |||
| 7a7a4844f4 | |||
| a2adbb1ab5 | |||
| a97fc792d8 | |||
| e9a6a1d6f5 | |||
| f245f0ef87 | |||
| a30f431b63 | |||
| 58f48f20e2 | |||
| ee1b02b709 | |||
| 55c790c9ff | |||
| 65b69f3308 | |||
| c67fbd72dd | |||
| 30f57d0824 | |||
| 1c54018111 | |||
| e80e1b6d9f | |||
| 437f00d6de | |||
| fc6d6b1601 | |||
| 9306e36d52 | |||
| 61122a5093 | |||
| a8a4ff8af1 | |||
| 8a857c35ee | |||
| 89ddd7d8e5 | |||
| 8d0c4ccb3b | |||
| 8ee47d5573 | |||
| 9e88011417 | |||
| f8949ee7a1 | |||
| 62aa2d0ba7 | |||
| ace047d625 | |||
| d6277db209 | |||
| 7ebb28327f | |||
| 86931cbde4 | |||
| 6d7be151dc | |||
| 07227b9806 | |||
| 8348d719cd | |||
| 0fcefd865b | |||
| 57c2e9b5f8 | |||
| 7d7fc39035 | |||
| 351105b3df | |||
| cbfc33215b | |||
| 5a93b56673 | |||
| 1f4c69c17a | |||
| f5b19fad20 | |||
| bc60818e9a | |||
| f82c88f016 | |||
| 98e86decad | |||
| aaf2c0ebd4 | |||
| 778b74cae1 | |||
| 43ee1edd97 | |||
| dd7e23740b | |||
| 1acd6da745 | |||
| 3056f91ec5 | |||
| ed03570e1a | |||
| 2ec0e48d06 | |||
| 8b54d59b8c | |||
| f6a4dbabdd | |||
| a71c291bcb | |||
| 55b9ccc2de |
+1
-1
@@ -1 +1 @@
|
||||
CMakeConf
|
||||
build
|
||||
|
||||
+14
-17
@@ -18,6 +18,10 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WIN32_IE 0x400
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -27,8 +31,7 @@
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WIN32_IE 0x400
|
||||
#ifdef _WIN32_IE
|
||||
#include <shlobj.h>
|
||||
#endif
|
||||
|
||||
@@ -219,13 +222,6 @@ void ReadALConfig(void)
|
||||
}
|
||||
#else
|
||||
f = fopen("/etc/openal/alsoft.conf", "r");
|
||||
if(!f)
|
||||
{
|
||||
f = fopen("/etc/openal/config", "r");
|
||||
if(f)
|
||||
AL_PRINT("Reading /etc/openal/config; this file is deprecated\n"
|
||||
"\tPlease rename it to /etc/openal/alsoft.conf\n");
|
||||
}
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -235,14 +231,6 @@ void ReadALConfig(void)
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", getenv("HOME"));
|
||||
f = fopen(buffer, "r");
|
||||
if(!f)
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "%s/.openalrc", getenv("HOME"));
|
||||
f = fopen(buffer, "r");
|
||||
if(f)
|
||||
AL_PRINT("Reading ~/.openalrc; this file is deprecated\n"
|
||||
"\tPlease rename it to ~/.alsoftrc\n");
|
||||
}
|
||||
if(f)
|
||||
{
|
||||
LoadConfigFromFile(f);
|
||||
@@ -325,3 +313,12 @@ float GetConfigValueFloat(const char *blockName, const char *keyName, float def)
|
||||
return (float)strtod(val, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
int GetConfigValueBool(const char *blockName, const char *keyName, float def)
|
||||
{
|
||||
const char *val = GetConfigValue(blockName, keyName, "");
|
||||
|
||||
if(!val[0]) return !!def;
|
||||
return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 ||
|
||||
strcasecmp(val, "on") == 0 || atoi(val) != 0);
|
||||
}
|
||||
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2009 by Chris Robinson.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alFilter.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alError.h"
|
||||
#include "alu.h"
|
||||
|
||||
typedef struct ALechoState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
ALfloat *SampleBuffer;
|
||||
ALuint BufferLength;
|
||||
|
||||
// The echo is two tap. The third tap is the offset to write the feedback
|
||||
// and input sample to
|
||||
struct {
|
||||
ALuint offset;
|
||||
} Tap[3];
|
||||
// The LR gains for the first tap. The second tap uses the reverse
|
||||
ALfloat GainL;
|
||||
ALfloat GainR;
|
||||
|
||||
ALfloat FeedGain;
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[2];
|
||||
} ALechoState;
|
||||
|
||||
// Find the next power of 2. Actually, this will return the input value if
|
||||
// it is already a power of 2.
|
||||
static ALuint NextPowerOf2(ALuint value)
|
||||
{
|
||||
ALuint powerOf2 = 1;
|
||||
|
||||
if(value)
|
||||
{
|
||||
value--;
|
||||
while(value)
|
||||
{
|
||||
value >>= 1;
|
||||
powerOf2 <<= 1;
|
||||
}
|
||||
}
|
||||
return powerOf2;
|
||||
}
|
||||
|
||||
ALvoid EchoDestroy(ALeffectState *effect)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
if(state)
|
||||
{
|
||||
free(state->SampleBuffer);
|
||||
state->SampleBuffer = NULL;
|
||||
free(state);
|
||||
}
|
||||
}
|
||||
|
||||
ALvoid EchoUpdate(ALeffectState *effect, ALCcontext *Context, ALeffect *Effect)
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
ALuint newdelay1, newdelay2;
|
||||
ALfloat lrpan, cw, a, g;
|
||||
|
||||
newdelay1 = (ALuint)(Effect->Echo.Delay * Context->Frequency);
|
||||
newdelay2 = (ALuint)(Effect->Echo.LRDelay * Context->Frequency);
|
||||
|
||||
state->Tap[0].offset = (state->BufferLength - newdelay1 - 1 +
|
||||
state->Tap[2].offset)%state->BufferLength;
|
||||
state->Tap[1].offset = (state->BufferLength - newdelay1 - newdelay2 - 1 +
|
||||
state->Tap[2].offset)%state->BufferLength;
|
||||
|
||||
lrpan = Effect->Echo.Spread*0.5f + 0.5f;
|
||||
state->GainL = aluSqrt( lrpan);
|
||||
state->GainR = aluSqrt(1.0f-lrpan);
|
||||
|
||||
state->FeedGain = Effect->Echo.Feedback;
|
||||
|
||||
cw = cos(2.0*M_PI * LOWPASSFREQCUTOFF / Context->Frequency);
|
||||
g = 1.0f - Effect->Echo.Damping;
|
||||
a = 0.0f;
|
||||
if(g < 0.9999f) // 1-epsilon
|
||||
a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
|
||||
state->iirFilter.coeff = a;
|
||||
}
|
||||
|
||||
ALvoid EchoProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS])
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
const ALuint delay = state->BufferLength-1;
|
||||
ALuint tap1off = state->Tap[0].offset;
|
||||
ALuint tap2off = state->Tap[1].offset;
|
||||
ALuint fboff = state->Tap[2].offset;
|
||||
ALfloat gain = Slot->Gain;
|
||||
ALfloat samp[2];
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
{
|
||||
// Apply damping
|
||||
samp[0] = lpFilter2P(&state->iirFilter, 0, state->SampleBuffer[tap2off]+SamplesIn[i]);
|
||||
|
||||
// Apply feedback gain and mix in the new sample
|
||||
state->SampleBuffer[fboff] = samp[0] * state->FeedGain;
|
||||
|
||||
tap1off = (tap1off+1) & delay;
|
||||
tap2off = (tap2off+1) & delay;
|
||||
fboff = (fboff+1) & delay;
|
||||
|
||||
// Sample first tap
|
||||
samp[0] = state->SampleBuffer[tap1off]*state->GainL;
|
||||
samp[1] = state->SampleBuffer[tap1off]*state->GainR;
|
||||
// Sample second tap. Reverse LR panning
|
||||
samp[0] += state->SampleBuffer[tap2off]*state->GainR;
|
||||
samp[1] += state->SampleBuffer[tap2off]*state->GainL;
|
||||
// Apply slot gain
|
||||
samp[0] *= gain;
|
||||
samp[1] *= gain;
|
||||
|
||||
SamplesOut[i][FRONT_LEFT] += samp[0];
|
||||
SamplesOut[i][FRONT_RIGHT] += samp[1];
|
||||
SamplesOut[i][SIDE_LEFT] += samp[0];
|
||||
SamplesOut[i][SIDE_RIGHT] += samp[1];
|
||||
SamplesOut[i][BACK_LEFT] += samp[0];
|
||||
SamplesOut[i][BACK_RIGHT] += samp[1];
|
||||
}
|
||||
|
||||
state->Tap[0].offset = tap1off;
|
||||
state->Tap[1].offset = tap2off;
|
||||
state->Tap[2].offset = fboff;
|
||||
}
|
||||
|
||||
ALeffectState *EchoCreate(ALCcontext *Context)
|
||||
{
|
||||
ALechoState *state;
|
||||
ALuint i, maxlen;
|
||||
|
||||
state = malloc(sizeof(*state));
|
||||
if(!state)
|
||||
{
|
||||
alSetError(AL_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
state->state.Destroy = EchoDestroy;
|
||||
state->state.Update = EchoUpdate;
|
||||
state->state.Process = EchoProcess;
|
||||
|
||||
maxlen = (ALuint)(AL_ECHO_MAX_DELAY * Context->Frequency);
|
||||
maxlen += (ALuint)(AL_ECHO_MAX_LRDELAY * Context->Frequency);
|
||||
|
||||
// Use the next power of 2 for the buffer length, so the tap offsets can be
|
||||
// wrapped using a mask instead of a modulo
|
||||
state->BufferLength = NextPowerOf2(maxlen+1);
|
||||
state->SampleBuffer = malloc(state->BufferLength * sizeof(ALfloat));
|
||||
if(!state->SampleBuffer)
|
||||
{
|
||||
free(state);
|
||||
alSetError(AL_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(i = 0;i < state->BufferLength;i++)
|
||||
state->SampleBuffer[i] = 0.0f;
|
||||
|
||||
state->Tap[0].offset = 0;
|
||||
state->Tap[1].offset = 0;
|
||||
state->Tap[2].offset = 0;
|
||||
state->GainL = 0.0f;
|
||||
state->GainR = 0.0f;
|
||||
|
||||
for(i = 0;i < 2;i++)
|
||||
state->iirFilter.history[i] = 0.0f;
|
||||
state->iirFilter.coeff = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
}
|
||||
+539
-303
File diff suppressed because it is too large
Load Diff
+4
-2
@@ -81,10 +81,11 @@ ALsizei RingBufferSize(RingBuffer *ring)
|
||||
|
||||
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
|
||||
{
|
||||
int remain = ring->length - ring->write_pos;
|
||||
int remain;
|
||||
|
||||
EnterCriticalSection(&ring->cs);
|
||||
|
||||
remain = ring->length - ring->write_pos;
|
||||
if((ring->read_pos-ring->write_pos+ring->length)%ring->length < len)
|
||||
ring->read_pos = (ring->write_pos+len) % ring->length;
|
||||
|
||||
@@ -104,10 +105,11 @@ void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
|
||||
|
||||
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
|
||||
{
|
||||
int remain = ring->length - ring->read_pos;
|
||||
int remain;
|
||||
|
||||
EnterCriticalSection(&ring->cs);
|
||||
|
||||
remain = ring->length - ring->read_pos;
|
||||
if(remain < len)
|
||||
{
|
||||
memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), remain*ring->frame_size);
|
||||
|
||||
+436
-472
File diff suppressed because it is too large
Load Diff
@@ -113,8 +113,6 @@ static void init(struct bs2b *bs2b)
|
||||
bs2b->a1_hi = -x;
|
||||
|
||||
bs2b->gain = 1.0 / (1.0 - G_hi + G_lo);
|
||||
|
||||
bs2b_clear(bs2b);
|
||||
} /* init */
|
||||
|
||||
/* Exported functions.
|
||||
|
||||
+229
-98
@@ -28,19 +28,29 @@
|
||||
|
||||
#include <dsound.h>
|
||||
#include <mmreg.h>
|
||||
#ifndef _WAVEFORMATEXTENSIBLE_
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
|
||||
#ifndef DSSPEAKER_5POINT1
|
||||
#define DSSPEAKER_5POINT1 6
|
||||
#endif
|
||||
#ifndef DSSPEAKER_7POINT1
|
||||
#define DSSPEAKER_7POINT1 7
|
||||
#endif
|
||||
|
||||
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
|
||||
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
|
||||
|
||||
static void *ds_handle;
|
||||
static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter);
|
||||
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
|
||||
|
||||
// Since DSound doesn't report the fragment size, emulate it
|
||||
static int num_frags;
|
||||
|
||||
typedef struct {
|
||||
// DirectSound Playback Device
|
||||
@@ -57,36 +67,53 @@ typedef struct {
|
||||
ALCchar *name;
|
||||
GUID guid;
|
||||
} DevMap;
|
||||
static DevMap DeviceList[16];
|
||||
|
||||
static const ALCchar dsDevice[] = "DirectSound Software";
|
||||
static DevMap *DeviceList;
|
||||
static ALuint NumDevices;
|
||||
|
||||
|
||||
static ALuint DSoundProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
DSoundData *pData = (DSoundData*)pDevice->ExtraData;
|
||||
DSBCAPS DSBCaps;
|
||||
DWORD LastCursor = 0;
|
||||
DWORD PlayCursor;
|
||||
VOID *WritePtr1, *WritePtr2;
|
||||
DWORD WriteCnt1, WriteCnt2;
|
||||
DWORD BufferSize;
|
||||
DWORD FrameSize;
|
||||
DWORD FragSize;
|
||||
DWORD avail;
|
||||
HRESULT err;
|
||||
|
||||
BufferSize = pDevice->UpdateSize * num_frags *
|
||||
aluBytesFromFormat(pDevice->Format) *
|
||||
aluChannelsFromFormat(pDevice->Format);
|
||||
memset(&DSBCaps, 0, sizeof(DSBCaps));
|
||||
DSBCaps.dwSize = sizeof(DSBCaps);
|
||||
err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps);
|
||||
if(FAILED(err))
|
||||
{
|
||||
AL_PRINT("Failed to get buffer caps: 0x%lx\n", err);
|
||||
aluHandleDisconnect(pDevice);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FrameSize = aluChannelsFromFormat(pDevice->Format) *
|
||||
aluBytesFromFormat(pDevice->Format);
|
||||
FragSize = pDevice->UpdateSize * FrameSize;
|
||||
|
||||
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
|
||||
while(!pData->killNow)
|
||||
{
|
||||
// Get current play and write cursors
|
||||
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
|
||||
avail = (PlayCursor-LastCursor+BufferSize) % BufferSize;
|
||||
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
|
||||
|
||||
if(avail < BufferSize/num_frags)
|
||||
if(avail < FragSize)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
avail -= avail%FragSize;
|
||||
|
||||
// Lock output buffer
|
||||
WriteCnt1 = 0;
|
||||
@@ -107,10 +134,8 @@ static ALuint DSoundProc(ALvoid *ptr)
|
||||
if(SUCCEEDED(err))
|
||||
{
|
||||
// If we have an active context, mix data directly into output buffer otherwise fill with silence
|
||||
SuspendContext(NULL);
|
||||
aluMixData(pDevice->Context, WritePtr1, WriteCnt1, pDevice->Format);
|
||||
aluMixData(pDevice->Context, WritePtr2, WriteCnt2, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize);
|
||||
aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize);
|
||||
|
||||
// Unlock output buffer only when successfully locked
|
||||
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
|
||||
@@ -120,7 +145,7 @@ static ALuint DSoundProc(ALvoid *ptr)
|
||||
|
||||
// Update old write cursor location
|
||||
LastCursor += WriteCnt1+WriteCnt2;
|
||||
LastCursor %= BufferSize;
|
||||
LastCursor %= DSBCaps.dwBufferBytes;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -128,34 +153,29 @@ static ALuint DSoundProc(ALvoid *ptr)
|
||||
|
||||
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
DSBUFFERDESC DSBDescription;
|
||||
DSoundData *pData = NULL;
|
||||
WAVEFORMATEXTENSIBLE OutputType;
|
||||
DWORD frameSize = 0;
|
||||
LPGUID guid = NULL;
|
||||
DWORD speakers;
|
||||
HRESULT hr;
|
||||
|
||||
if(deviceName)
|
||||
if(ds_handle == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = dsDevice;
|
||||
else if(strcmp(deviceName, dsDevice) != 0)
|
||||
{
|
||||
int i;
|
||||
for(i = 0;DeviceList[i].name;i++)
|
||||
ALuint i;
|
||||
for(i = 0;i < NumDevices;i++)
|
||||
{
|
||||
if(strcmp(deviceName, DeviceList[i].name) == 0)
|
||||
{
|
||||
device->szDeviceName = DeviceList[i].name;
|
||||
if(i > 0)
|
||||
guid = &DeviceList[i].guid;
|
||||
guid = &DeviceList[i].guid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!DeviceList[i].name)
|
||||
if(i == NumDevices)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = DeviceList[0].name;
|
||||
|
||||
memset(&OutputType, 0, sizeof(OutputType));
|
||||
|
||||
//Initialise requested device
|
||||
|
||||
@@ -167,28 +187,60 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
}
|
||||
|
||||
//DirectSound Init code
|
||||
hr = DirectSoundCreate(guid, &pData->lpDS, NULL);
|
||||
hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(*(GetConfigValue(NULL, "format", "")) == 0)
|
||||
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
|
||||
if(pData->lpDS)
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
free(pData);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = pData;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void DSoundClosePlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundData *pData = device->ExtraData;
|
||||
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
free(pData);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean DSoundResetPlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundData *pData = (DSoundData*)device->ExtraData;
|
||||
DSBUFFERDESC DSBDescription;
|
||||
WAVEFORMATEXTENSIBLE OutputType;
|
||||
DWORD frameSize = 0;
|
||||
ALenum format = 0;
|
||||
DWORD speakers;
|
||||
HRESULT hr;
|
||||
|
||||
memset(&OutputType, 0, sizeof(OutputType));
|
||||
|
||||
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
|
||||
if(SUCCEEDED(hr) && *(GetConfigValue(NULL, "format", "")) != 0)
|
||||
{
|
||||
if(aluChannelsFromFormat(device->Format) == 1)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
|
||||
else if(aluChannelsFromFormat(device->Format) == 2)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
|
||||
else if(aluChannelsFromFormat(device->Format) == 4)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
|
||||
else if(aluChannelsFromFormat(device->Format) == 6)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
|
||||
else if(aluChannelsFromFormat(device->Format) == 8)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
|
||||
else
|
||||
{
|
||||
if(device->Format == AL_FORMAT_MONO8 || device->Format == AL_FORMAT_MONO16)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
|
||||
else if(device->Format == AL_FORMAT_STEREO8 || device->Format == AL_FORMAT_STEREO16)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
|
||||
else if(device->Format == AL_FORMAT_QUAD8 || device->Format == AL_FORMAT_QUAD16)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
|
||||
else if(device->Format == AL_FORMAT_51CHN8 || device->Format == AL_FORMAT_51CHN16)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
|
||||
else if(device->Format == AL_FORMAT_71CHN8 || device->Format == AL_FORMAT_71CHN16)
|
||||
speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
|
||||
else
|
||||
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
@@ -197,23 +249,29 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
if(speakers == DSSPEAKER_MONO)
|
||||
{
|
||||
if(aluBytesFromFormat(device->Format) == 1)
|
||||
device->Format = AL_FORMAT_MONO8;
|
||||
else
|
||||
device->Format = AL_FORMAT_MONO16;
|
||||
format = AL_FORMAT_MONO8;
|
||||
else if(aluBytesFromFormat(device->Format) == 2)
|
||||
format = AL_FORMAT_MONO16;
|
||||
else if(aluBytesFromFormat(device->Format) == 4)
|
||||
format = AL_FORMAT_MONO_FLOAT32;
|
||||
}
|
||||
else if(speakers == DSSPEAKER_STEREO)
|
||||
{
|
||||
if(aluBytesFromFormat(device->Format) == 1)
|
||||
device->Format = AL_FORMAT_STEREO8;
|
||||
else
|
||||
device->Format = AL_FORMAT_STEREO16;
|
||||
format = AL_FORMAT_STEREO8;
|
||||
else if(aluBytesFromFormat(device->Format) == 2)
|
||||
format = AL_FORMAT_STEREO16;
|
||||
else if(aluBytesFromFormat(device->Format) == 4)
|
||||
format = AL_FORMAT_STEREO_FLOAT32;
|
||||
}
|
||||
else if(speakers == DSSPEAKER_QUAD)
|
||||
{
|
||||
if(aluBytesFromFormat(device->Format) == 1)
|
||||
device->Format = AL_FORMAT_QUAD8;
|
||||
else
|
||||
device->Format = AL_FORMAT_QUAD16;
|
||||
format = AL_FORMAT_QUAD8;
|
||||
else if(aluBytesFromFormat(device->Format) == 2)
|
||||
format = AL_FORMAT_QUAD16;
|
||||
else if(aluBytesFromFormat(device->Format) == 4)
|
||||
format = AL_FORMAT_QUAD32;
|
||||
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
|
||||
SPEAKER_FRONT_RIGHT |
|
||||
SPEAKER_BACK_LEFT |
|
||||
@@ -222,9 +280,11 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
else if(speakers == DSSPEAKER_5POINT1)
|
||||
{
|
||||
if(aluBytesFromFormat(device->Format) == 1)
|
||||
device->Format = AL_FORMAT_51CHN8;
|
||||
else
|
||||
device->Format = AL_FORMAT_51CHN16;
|
||||
format = AL_FORMAT_51CHN8;
|
||||
else if(aluBytesFromFormat(device->Format) == 2)
|
||||
format = AL_FORMAT_51CHN16;
|
||||
else if(aluBytesFromFormat(device->Format) == 4)
|
||||
format = AL_FORMAT_51CHN32;
|
||||
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
|
||||
SPEAKER_FRONT_RIGHT |
|
||||
SPEAKER_FRONT_CENTER |
|
||||
@@ -235,9 +295,11 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
else if(speakers == DSSPEAKER_7POINT1)
|
||||
{
|
||||
if(aluBytesFromFormat(device->Format) == 1)
|
||||
device->Format = AL_FORMAT_71CHN8;
|
||||
else
|
||||
device->Format = AL_FORMAT_71CHN16;
|
||||
format = AL_FORMAT_71CHN8;
|
||||
else if(aluBytesFromFormat(device->Format) == 2)
|
||||
format = AL_FORMAT_71CHN16;
|
||||
else if(aluBytesFromFormat(device->Format) == 4)
|
||||
format = AL_FORMAT_71CHN32;
|
||||
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
|
||||
SPEAKER_FRONT_RIGHT |
|
||||
SPEAKER_FRONT_CENTER |
|
||||
@@ -247,26 +309,28 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
SPEAKER_SIDE_LEFT |
|
||||
SPEAKER_SIDE_RIGHT;
|
||||
}
|
||||
frameSize = aluBytesFromFormat(device->Format) *
|
||||
aluChannelsFromFormat(device->Format);
|
||||
else
|
||||
format = device->Format;
|
||||
frameSize = aluBytesFromFormat(format) * aluChannelsFromFormat(format);
|
||||
|
||||
OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
OutputType.Format.nChannels = aluChannelsFromFormat(device->Format);
|
||||
OutputType.Format.wBitsPerSample = aluBytesFromFormat(device->Format) * 8;
|
||||
OutputType.Format.nChannels = aluChannelsFromFormat(format);
|
||||
OutputType.Format.wBitsPerSample = aluBytesFromFormat(format) * 8;
|
||||
OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
|
||||
OutputType.Format.nSamplesPerSec = device->Frequency;
|
||||
OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
|
||||
OutputType.Format.cbSize = 0;
|
||||
|
||||
device->UpdateSize /= num_frags;
|
||||
}
|
||||
|
||||
if(OutputType.Format.nChannels > 2)
|
||||
if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
|
||||
{
|
||||
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
|
||||
OutputType.Format.cbSize = 22;
|
||||
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
if(OutputType.Format.wBitsPerSample == 32)
|
||||
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
else
|
||||
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -286,7 +350,7 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
|
||||
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
|
||||
DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
|
||||
DSBDescription.dwBufferBytes=device->UpdateSize * num_frags * frameSize;
|
||||
DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize;
|
||||
DSBDescription.lpwfxFormat=&OutputType.Format;
|
||||
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
|
||||
}
|
||||
@@ -306,42 +370,41 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
{
|
||||
if (pData->DSsbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
pData->DSsbuffer = NULL;
|
||||
if (pData->DSpbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
if (pData->lpDS)
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
|
||||
free(pData);
|
||||
pData->DSpbuffer = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Format = format;
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void DSoundClosePlayback(ALCdevice *device)
|
||||
static void DSoundStopPlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundData *pData = device->ExtraData;
|
||||
|
||||
if(!pData->thread)
|
||||
return;
|
||||
|
||||
pData->killNow = 1;
|
||||
StopThread(pData->thread);
|
||||
pData->thread = NULL;
|
||||
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
pData->DSsbuffer = NULL;
|
||||
if (pData->DSpbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
|
||||
free(pData);
|
||||
device->ExtraData = NULL;
|
||||
pData->DSpbuffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
{
|
||||
(void)pDevice;
|
||||
(void)deviceName;
|
||||
(void)frequency;
|
||||
(void)format;
|
||||
(void)SampleSize;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -377,6 +440,8 @@ static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
|
||||
BackendFuncs DSoundFuncs = {
|
||||
DSoundOpenPlayback,
|
||||
DSoundClosePlayback,
|
||||
DSoundResetPlayback,
|
||||
DSoundStopPlayback,
|
||||
DSoundOpenCapture,
|
||||
DSoundCloseCapture,
|
||||
DSoundStartCapture,
|
||||
@@ -387,34 +452,100 @@ BackendFuncs DSoundFuncs = {
|
||||
|
||||
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
|
||||
{
|
||||
size_t *iter = data;
|
||||
(void)data;
|
||||
(void)drvname;
|
||||
|
||||
if(guid)
|
||||
{
|
||||
char str[128];
|
||||
snprintf(str, sizeof(str), "DirectSound Software on %s", desc);
|
||||
DeviceList[*iter].name = AppendAllDeviceList(str);
|
||||
DeviceList[*iter].guid = *guid;
|
||||
(*iter)++;
|
||||
void *temp;
|
||||
|
||||
temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
|
||||
if(temp)
|
||||
{
|
||||
DeviceList = temp;
|
||||
|
||||
snprintf(str, sizeof(str), "DirectSound Software on %s", desc);
|
||||
AppendAllDeviceList(str);
|
||||
|
||||
DeviceList[NumDevices].name = strdup(str);
|
||||
DeviceList[NumDevices].guid = *guid;
|
||||
NumDevices++;
|
||||
}
|
||||
}
|
||||
else
|
||||
DeviceList[0].name = AppendDeviceList("DirectSound Software");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void alcDSoundInit(BackendFuncs *FuncList)
|
||||
{
|
||||
size_t iter = 1;
|
||||
HRESULT hr;
|
||||
if(FuncList) *FuncList = DSoundFuncs;
|
||||
|
||||
*FuncList = DSoundFuncs;
|
||||
#ifdef _WIN32
|
||||
ds_handle = LoadLibraryA("dsound.dll");
|
||||
if(ds_handle == NULL)
|
||||
{
|
||||
AL_PRINT("Failed to load dsound.dll\n");
|
||||
return;
|
||||
}
|
||||
|
||||
num_frags = GetConfigValueInt("dsound", "periods", 4);
|
||||
if(num_frags < 2) num_frags = 2;
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = (void*)GetProcAddress((HMODULE)ds_handle, #f); \
|
||||
if(p##f == NULL) \
|
||||
{ \
|
||||
FreeLibrary(ds_handle); \
|
||||
ds_handle = NULL; \
|
||||
AL_PRINT("Could not load %s from dsound.dll\n", #f); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
ds_handle = (void*)0xDEADBEEF;
|
||||
#define LOAD_FUNC(f) p##f = f
|
||||
#endif
|
||||
|
||||
hr = DirectSoundEnumerate(DSoundEnumDevices, &iter);
|
||||
if(FAILED(hr))
|
||||
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
|
||||
LOAD_FUNC(DirectSoundCreate);
|
||||
LOAD_FUNC(DirectSoundEnumerateA);
|
||||
#undef LOAD_FUNC
|
||||
}
|
||||
|
||||
void alcDSoundDeinit(void)
|
||||
{
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < NumDevices;++i)
|
||||
free(DeviceList[i].name);
|
||||
free(DeviceList);
|
||||
DeviceList = NULL;
|
||||
NumDevices = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if(ds_handle)
|
||||
FreeLibrary(ds_handle);
|
||||
#endif
|
||||
ds_handle = NULL;
|
||||
}
|
||||
|
||||
void alcDSoundProbe(int type)
|
||||
{
|
||||
if(!ds_handle) alcDSoundInit(NULL);
|
||||
if(!ds_handle) return;
|
||||
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(dsDevice);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
{
|
||||
HRESULT hr;
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < NumDevices;++i)
|
||||
free(DeviceList[i].name);
|
||||
free(DeviceList);
|
||||
DeviceList = NULL;
|
||||
NumDevices = 0;
|
||||
|
||||
hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
|
||||
if(FAILED(hr))
|
||||
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
#define SOUND_MIXER_WRITE MIXER_WRITE
|
||||
#endif
|
||||
|
||||
static char *oss_device;
|
||||
static char *oss_device_capture;
|
||||
static const ALCchar oss_device[] = "OSS Software";
|
||||
static const ALCchar oss_device_capture[] = "OSS Capture";
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
@@ -79,35 +79,37 @@ static ALuint OSSProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
int remaining = 0;
|
||||
ALint frameSize;
|
||||
int wrote;
|
||||
|
||||
while(!data->killNow)
|
||||
frameSize = aluChannelsFromFormat(pDevice->Format) *
|
||||
aluBytesFromFormat(pDevice->Format);
|
||||
|
||||
while(!data->killNow && !pDevice->Connected)
|
||||
{
|
||||
int len = data->data_size - remaining;
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
if(len > 0)
|
||||
aluMixData(pDevice, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
}
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
if(wrote < 0)
|
||||
{
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
{
|
||||
AL_PRINT("write failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
remaining += len;
|
||||
wrote = write(data->fd, data->mix_data, remaining);
|
||||
if(wrote < 0)
|
||||
{
|
||||
AL_PRINT("write failed: %s\n", strerror(errno));
|
||||
remaining = 0;
|
||||
len -= wrote;
|
||||
WritePtr += wrote;
|
||||
}
|
||||
else if(wrote > 0)
|
||||
{
|
||||
remaining -= wrote;
|
||||
if(remaining > 0)
|
||||
memmove(data->mix_data, data->mix_data+wrote, remaining);
|
||||
}
|
||||
else
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -129,6 +131,7 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
if(amt < 0)
|
||||
{
|
||||
AL_PRINT("read failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
break;
|
||||
}
|
||||
if(amt == 0)
|
||||
@@ -145,29 +148,15 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
|
||||
static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
ALuint frameSize;
|
||||
char driver[64];
|
||||
int numChannels;
|
||||
oss_data *data;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, oss_device))
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = oss_device;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = oss_device;
|
||||
if(!deviceName)
|
||||
deviceName = oss_device;
|
||||
else if(strcmp(deviceName, oss_device) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
@@ -180,31 +169,71 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void oss_close_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
|
||||
close(data->fd);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean oss_reset_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
unsigned int periods;
|
||||
audio_buf_info info;
|
||||
ALuint frameSize;
|
||||
int numChannels;
|
||||
int ossFormat;
|
||||
int ossSpeed;
|
||||
char *err;
|
||||
int i;
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
ossFormat = AFMT_U8;
|
||||
break;
|
||||
case 4:
|
||||
switch(aluChannelsFromFormat(device->Format))
|
||||
{
|
||||
case 1: device->Format = AL_FORMAT_MONO16; break;
|
||||
case 2: device->Format = AL_FORMAT_STEREO16; break;
|
||||
case 4: device->Format = AL_FORMAT_QUAD16; break;
|
||||
case 6: device->Format = AL_FORMAT_51CHN16; break;
|
||||
case 7: device->Format = AL_FORMAT_61CHN16; break;
|
||||
case 8: device->Format = AL_FORMAT_71CHN16; break;
|
||||
}
|
||||
/* fall-through */
|
||||
case 2:
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
default:
|
||||
ossFormat = -1;
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
periods = GetConfigValueInt("oss", "periods", 4);
|
||||
if((int)periods <= 0)
|
||||
periods = 4;
|
||||
periods = device->NumUpdates;
|
||||
numChannels = aluChannelsFromFormat(device->Format);
|
||||
frameSize = numChannels * aluBytesFromFormat(device->Format);
|
||||
|
||||
ossSpeed = device->Frequency;
|
||||
log2FragmentSize = log2i(device->UpdateSize * frameSize / periods);
|
||||
log2FragmentSize = log2i(device->UpdateSize * frameSize);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
log2FragmentSize = 4;
|
||||
/* Subtract one period since the temp mixing buffer counts as one. Still
|
||||
* need at least two on the card, though. */
|
||||
if(periods > 2) periods--;
|
||||
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
|
||||
|
||||
#define ok(func, str) (i=(func),((i<0)?(err=(str)),0:1))
|
||||
@@ -215,19 +244,13 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
|
||||
ok(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info), "get space")))
|
||||
{
|
||||
AL_PRINT("%s failed: %s\n", err, strerror(errno));
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
#undef ok
|
||||
|
||||
device->Frequency = ossSpeed;
|
||||
|
||||
if((int)aluChannelsFromFormat(device->Format) != numChannels)
|
||||
{
|
||||
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), numChannels);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -235,44 +258,44 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
|
||||
(ossFormat == AFMT_S16_NE && aluBytesFromFormat(device->Format) == 2)))
|
||||
{
|
||||
AL_PRINT("Could not set %d-bit output, got format %#x\n", aluBytesFromFormat(device->Format)*8, ossFormat);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Frequency = ossSpeed;
|
||||
device->UpdateSize = info.fragsize / frameSize;
|
||||
device->NumUpdates = info.fragments + 1;
|
||||
|
||||
data->data_size = device->UpdateSize * frameSize;
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(OSSProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
data->mix_data = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void oss_close_playback(ALCdevice *device)
|
||||
static void oss_stop_playback(ALCdevice *device)
|
||||
{
|
||||
oss_data *data = (oss_data*)device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
|
||||
close(data->fd);
|
||||
data->thread = NULL;
|
||||
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
data->mix_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
int numFragmentsLogSize;
|
||||
int log2FragmentSize;
|
||||
@@ -289,14 +312,10 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
|
||||
|
||||
strncpy(driver, GetConfigValue("oss", "capture", "/dev/dsp"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, oss_device_capture))
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = oss_device_capture;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = oss_device_capture;
|
||||
if(!deviceName)
|
||||
deviceName = oss_device_capture;
|
||||
else if(strcmp(deviceName, oss_device_capture) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = (oss_data*)calloc(1, sizeof(oss_data));
|
||||
data->killNow = 0;
|
||||
@@ -309,7 +328,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
switch(aluBytesFromFormat(format))
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
ossFormat = AFMT_U8;
|
||||
@@ -318,15 +337,18 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
|
||||
ossFormat = AFMT_S16_NE;
|
||||
break;
|
||||
default:
|
||||
ossFormat = -1;
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
periods = 4;
|
||||
numChannels = aluChannelsFromFormat(device->Format);
|
||||
frameSize = numChannels * aluBytesFromFormat(device->Format);
|
||||
ossSpeed = frequency;
|
||||
log2FragmentSize = log2i(SampleSize * frameSize / periods);
|
||||
ossSpeed = device->Frequency;
|
||||
log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates *
|
||||
frameSize / periods);
|
||||
|
||||
/* according to the OSS spec, 16 bytes are the minimum */
|
||||
if (log2FragmentSize < 4)
|
||||
@@ -364,7 +386,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->ring = CreateRingBuffer(frameSize, SampleSize);
|
||||
data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
|
||||
if(!data->ring)
|
||||
{
|
||||
AL_PRINT("ring buffer create failed\n");
|
||||
@@ -386,6 +408,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
@@ -435,6 +458,8 @@ static ALCuint oss_available_samples(ALCdevice *pDevice)
|
||||
BackendFuncs oss_funcs = {
|
||||
oss_open_playback,
|
||||
oss_close_playback,
|
||||
oss_reset_playback,
|
||||
oss_stop_playback,
|
||||
oss_open_capture,
|
||||
oss_close_capture,
|
||||
oss_start_capture,
|
||||
@@ -446,9 +471,18 @@ BackendFuncs oss_funcs = {
|
||||
void alc_oss_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = oss_funcs;
|
||||
|
||||
oss_device = AppendDeviceList("OSS Software");
|
||||
AppendAllDeviceList(oss_device);
|
||||
|
||||
oss_device_capture = AppendCaptureDeviceList("OSS Capture");
|
||||
}
|
||||
|
||||
void alc_oss_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_oss_probe(int type)
|
||||
{
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(oss_device);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
AppendAllDeviceList(oss_device);
|
||||
else if(type == CAPTURE_DEVICE_PROBE)
|
||||
AppendCaptureDeviceList(oss_device_capture);
|
||||
}
|
||||
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <portaudio.h>
|
||||
|
||||
static void *pa_handle;
|
||||
#define MAKE_FUNC(x) static typeof(x) * p##x
|
||||
MAKE_FUNC(Pa_Initialize);
|
||||
MAKE_FUNC(Pa_Terminate);
|
||||
MAKE_FUNC(Pa_GetErrorText);
|
||||
MAKE_FUNC(Pa_StartStream);
|
||||
MAKE_FUNC(Pa_StopStream);
|
||||
MAKE_FUNC(Pa_OpenStream);
|
||||
MAKE_FUNC(Pa_CloseStream);
|
||||
MAKE_FUNC(Pa_GetDefaultOutputDevice);
|
||||
MAKE_FUNC(Pa_GetStreamInfo);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
|
||||
static const ALCchar pa_device[] = "PortAudio Software";
|
||||
|
||||
typedef struct {
|
||||
PaStream *stream;
|
||||
} pa_data;
|
||||
|
||||
|
||||
static int pa_callback(const void *inputBuffer, void *outputBuffer,
|
||||
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
|
||||
const PaStreamCallbackFlags statusFlags, void *userData)
|
||||
{
|
||||
ALCdevice *device = (ALCdevice*)userData;
|
||||
|
||||
(void)inputBuffer;
|
||||
(void)timeInfo;
|
||||
(void)statusFlags;
|
||||
|
||||
aluMixData(device, outputBuffer, framesPerBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
const PaStreamInfo *streamInfo;
|
||||
PaStreamParameters outParams;
|
||||
pa_data *data;
|
||||
PaError err;
|
||||
|
||||
if(pa_handle == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
if(!deviceName)
|
||||
deviceName = pa_device;
|
||||
else if(strcmp(deviceName, pa_device) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = (pa_data*)calloc(1, sizeof(pa_data));
|
||||
device->ExtraData = data;
|
||||
|
||||
outParams.device = GetConfigValueInt("port", "device", -1);
|
||||
if(outParams.device < 0)
|
||||
outParams.device = pPa_GetDefaultOutputDevice();
|
||||
outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
|
||||
(float)device->Frequency;
|
||||
outParams.hostApiSpecificStreamInfo = NULL;
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
outParams.sampleFormat = paUInt8;
|
||||
break;
|
||||
case 2:
|
||||
outParams.sampleFormat = paInt16;
|
||||
break;
|
||||
case 4:
|
||||
outParams.sampleFormat = paFloat32;
|
||||
break;
|
||||
default:
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
device->ExtraData = NULL;
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
outParams.channelCount = aluChannelsFromFormat(device->Format);
|
||||
|
||||
err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
|
||||
device->UpdateSize, paNoFlag, pa_callback, device);
|
||||
if(err != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
device->ExtraData = NULL;
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
streamInfo = pPa_GetStreamInfo(data->stream);
|
||||
|
||||
err = pPa_StartStream(data->stream);
|
||||
if(err != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_StartStream() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
pPa_CloseStream(data->stream);
|
||||
device->ExtraData = NULL;
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->Frequency = streamInfo->sampleRate;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void pa_close_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
PaError err;
|
||||
|
||||
err = pPa_StopStream(data->stream);
|
||||
if(err != paNoError)
|
||||
fprintf(stderr, "Error stopping stream: %s\n", pPa_GetErrorText(err));
|
||||
|
||||
err = pPa_CloseStream(data->stream);
|
||||
if(err != paNoError)
|
||||
fprintf(stderr, "Error closing stream: %s\n", pPa_GetErrorText(err));
|
||||
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean pa_reset_playback(ALCdevice *device)
|
||||
{
|
||||
pa_data *data = (pa_data*)device->ExtraData;
|
||||
const PaStreamInfo *streamInfo;
|
||||
|
||||
streamInfo = pPa_GetStreamInfo(data->stream);
|
||||
device->Frequency = streamInfo->sampleRate;
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void pa_stop_playback(ALCdevice *device)
|
||||
{
|
||||
(void)device;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
return ALC_FALSE;
|
||||
(void)device;
|
||||
(void)deviceName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const BackendFuncs pa_funcs = {
|
||||
pa_open_playback,
|
||||
pa_close_playback,
|
||||
pa_reset_playback,
|
||||
pa_stop_playback,
|
||||
pa_open_capture,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
void alc_pa_init(BackendFuncs *func_list)
|
||||
{
|
||||
const char *str;
|
||||
PaError err;
|
||||
|
||||
if(func_list) *func_list = pa_funcs;
|
||||
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# define PALIB "libportaudio.2.dylib"
|
||||
#else
|
||||
# define PALIB "libportaudio.so.2"
|
||||
#endif
|
||||
pa_handle = dlopen(PALIB, RTLD_NOW);
|
||||
if(!pa_handle)
|
||||
return;
|
||||
dlerror();
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = (typeof(f)*)dlsym(pa_handle, #f); \
|
||||
if((str=dlerror()) != NULL) \
|
||||
{ \
|
||||
dlclose(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
AL_PRINT("Could not load %s from "PALIB": %s\n", #f, str); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
#else
|
||||
str = NULL;
|
||||
pa_handle = (void*)0xDEADBEEF;
|
||||
#define LOAD_FUNC(f) p##f = f
|
||||
#endif
|
||||
|
||||
LOAD_FUNC(Pa_Initialize);
|
||||
LOAD_FUNC(Pa_Terminate);
|
||||
LOAD_FUNC(Pa_GetErrorText);
|
||||
LOAD_FUNC(Pa_StartStream);
|
||||
LOAD_FUNC(Pa_StopStream);
|
||||
LOAD_FUNC(Pa_OpenStream);
|
||||
LOAD_FUNC(Pa_CloseStream);
|
||||
LOAD_FUNC(Pa_GetDefaultOutputDevice);
|
||||
LOAD_FUNC(Pa_GetStreamInfo);
|
||||
#undef LOAD_FUNC
|
||||
|
||||
if((err=pPa_Initialize()) != paNoError)
|
||||
{
|
||||
AL_PRINT("Pa_Initialize() returned an error: %s\n", pPa_GetErrorText(err));
|
||||
alc_pa_deinit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void alc_pa_deinit(void)
|
||||
{
|
||||
if(pa_handle)
|
||||
{
|
||||
pPa_Terminate();
|
||||
#ifdef HAVE_DLFCN_H
|
||||
dlclose(pa_handle);
|
||||
pa_handle = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void alc_pa_probe(int type)
|
||||
{
|
||||
if(!pa_handle) alc_pa_init(NULL);
|
||||
if(!pa_handle) return;
|
||||
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(pa_device);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
AppendAllDeviceList(pa_device);
|
||||
}
|
||||
@@ -0,0 +1,671 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 2009 by Konstantinos Natsakis <konstantinos.natsakis@gmail.com>
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alMain.h"
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
#if PA_API_VERSION == 11
|
||||
#define PA_STREAM_ADJUST_LATENCY 0x2000U
|
||||
static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
|
||||
{
|
||||
return (x == PA_STREAM_CREATING || x == PA_STREAM_READY);
|
||||
}
|
||||
static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
|
||||
{
|
||||
return (x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING ||
|
||||
x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY);
|
||||
}
|
||||
#define PA_STREAM_IS_GOOD PA_STREAM_IS_GOOD
|
||||
#define PA_CONTEXT_IS_GOOD PA_CONTEXT_IS_GOOD
|
||||
#elif PA_API_VERSION != 12
|
||||
#error Invalid PulseAudio API version
|
||||
#endif
|
||||
|
||||
static void *pa_handle;
|
||||
#define MAKE_FUNC(x) static typeof(x) * p##x
|
||||
MAKE_FUNC(pa_context_unref);
|
||||
MAKE_FUNC(pa_sample_spec_valid);
|
||||
MAKE_FUNC(pa_stream_drop);
|
||||
MAKE_FUNC(pa_strerror);
|
||||
MAKE_FUNC(pa_context_get_state);
|
||||
MAKE_FUNC(pa_stream_get_state);
|
||||
MAKE_FUNC(pa_threaded_mainloop_signal);
|
||||
MAKE_FUNC(pa_stream_peek);
|
||||
MAKE_FUNC(pa_threaded_mainloop_wait);
|
||||
MAKE_FUNC(pa_threaded_mainloop_unlock);
|
||||
MAKE_FUNC(pa_context_new);
|
||||
MAKE_FUNC(pa_threaded_mainloop_stop);
|
||||
MAKE_FUNC(pa_context_disconnect);
|
||||
MAKE_FUNC(pa_threaded_mainloop_start);
|
||||
MAKE_FUNC(pa_threaded_mainloop_get_api);
|
||||
MAKE_FUNC(pa_context_set_state_callback);
|
||||
MAKE_FUNC(pa_stream_write);
|
||||
MAKE_FUNC(pa_xfree);
|
||||
MAKE_FUNC(pa_stream_connect_record);
|
||||
MAKE_FUNC(pa_stream_connect_playback);
|
||||
MAKE_FUNC(pa_path_get_filename);
|
||||
MAKE_FUNC(pa_get_binary_name);
|
||||
MAKE_FUNC(pa_threaded_mainloop_free);
|
||||
MAKE_FUNC(pa_context_errno);
|
||||
MAKE_FUNC(pa_xmalloc0);
|
||||
MAKE_FUNC(pa_stream_unref);
|
||||
MAKE_FUNC(pa_threaded_mainloop_accept);
|
||||
MAKE_FUNC(pa_stream_set_write_callback);
|
||||
MAKE_FUNC(pa_threaded_mainloop_new);
|
||||
MAKE_FUNC(pa_context_connect);
|
||||
MAKE_FUNC(pa_stream_get_buffer_attr);
|
||||
MAKE_FUNC(pa_stream_set_read_callback);
|
||||
MAKE_FUNC(pa_stream_set_state_callback);
|
||||
MAKE_FUNC(pa_stream_new);
|
||||
MAKE_FUNC(pa_stream_disconnect);
|
||||
MAKE_FUNC(pa_threaded_mainloop_lock);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
ALCuint samples;
|
||||
ALCuint frame_size;
|
||||
|
||||
RingBuffer *ring;
|
||||
|
||||
pa_buffer_attr attr;
|
||||
pa_sample_spec spec;
|
||||
|
||||
char path_name[PATH_MAX];
|
||||
const char *context_name;
|
||||
const char *stream_name;
|
||||
|
||||
pa_threaded_mainloop *loop;
|
||||
|
||||
pa_stream *stream;
|
||||
pa_context *context;
|
||||
} pulse_data;
|
||||
|
||||
static const ALCchar pulse_device[] = "PulseAudio Software";
|
||||
static const ALCchar pulse_capture_device[] = "PulseAudio Capture";
|
||||
|
||||
|
||||
// PulseAudio I/O Callbacks //{{{
|
||||
static void stream_write_callback(pa_stream *stream, size_t len, void *pdata) //{{{
|
||||
{
|
||||
ALCdevice *Device = pdata;
|
||||
pulse_data *data = Device->ExtraData;
|
||||
void *buf = ppa_xmalloc0(data->attr.minreq);
|
||||
(void)len;
|
||||
|
||||
aluMixData(Device, buf, data->attr.minreq/data->frame_size);
|
||||
ppa_stream_write(stream, buf, data->attr.minreq, ppa_xfree, 0,
|
||||
PA_SEEK_RELATIVE);
|
||||
} //}}}
|
||||
|
||||
static void stream_read_callback(pa_stream *stream, size_t length, void *pdata) //{{{
|
||||
{
|
||||
ALCdevice *Device = pdata;
|
||||
pulse_data *data = Device->ExtraData;
|
||||
const void *buf;
|
||||
|
||||
if(ppa_stream_peek(stream, &buf, &length) < 0)
|
||||
{
|
||||
AL_PRINT("pa_stream_peek() failed: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
return;
|
||||
}
|
||||
|
||||
assert(buf);
|
||||
assert(length);
|
||||
|
||||
length /= data->frame_size;
|
||||
|
||||
if(data->samples < length)
|
||||
AL_PRINT("stream_read_callback: buffer overflow!\n");
|
||||
|
||||
WriteRingBuffer(data->ring, buf, (length<data->samples) ? length : data->samples);
|
||||
|
||||
ppa_stream_drop(stream);
|
||||
} //}}}
|
||||
//}}}
|
||||
|
||||
static ALCboolean pulse_open(ALCdevice *device, const ALCchar *device_name) //{{{
|
||||
{
|
||||
pulse_data *data = ppa_xmalloc0(sizeof(pulse_data));
|
||||
pa_context_state_t state;
|
||||
|
||||
if(ppa_get_binary_name(data->path_name, sizeof(data->path_name)))
|
||||
data->context_name = ppa_path_get_filename(data->path_name);
|
||||
else
|
||||
data->context_name = "OpenAL Soft";
|
||||
|
||||
if(!(data->loop = ppa_threaded_mainloop_new()))
|
||||
{
|
||||
AL_PRINT("pa_threaded_mainloop_new() failed!\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(ppa_threaded_mainloop_start(data->loop) < 0)
|
||||
{
|
||||
AL_PRINT("pa_threaded_mainloop_start() failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
data->context = ppa_context_new(ppa_threaded_mainloop_get_api(data->loop), data->context_name);
|
||||
if(!data->context)
|
||||
{
|
||||
AL_PRINT("pa_context_new() failed: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(ppa_context_connect(data->context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL) < 0)
|
||||
{
|
||||
AL_PRINT("Context did not connect: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_context_unref(data->context);
|
||||
data->context = NULL;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while((state=ppa_context_get_state(data->context)) != PA_CONTEXT_READY)
|
||||
{
|
||||
if(!PA_CONTEXT_IS_GOOD(state))
|
||||
{
|
||||
AL_PRINT("Context did not get ready: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_context_unref(data->context);
|
||||
data->context = NULL;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
Sleep(1);
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(device_name);
|
||||
device->ExtraData = data;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_TRUE;
|
||||
|
||||
out:
|
||||
if(data->loop)
|
||||
{
|
||||
ppa_threaded_mainloop_stop(data->loop);
|
||||
ppa_threaded_mainloop_free(data->loop);
|
||||
}
|
||||
|
||||
ppa_xfree(data);
|
||||
return ALC_FALSE;
|
||||
} //}}}
|
||||
|
||||
static void pulse_close(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
if(data->stream)
|
||||
{
|
||||
ppa_stream_disconnect(data->stream);
|
||||
ppa_stream_unref(data->stream);
|
||||
}
|
||||
|
||||
ppa_context_disconnect(data->context);
|
||||
ppa_context_unref(data->context);
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
ppa_threaded_mainloop_stop(data->loop);
|
||||
ppa_threaded_mainloop_free(data->loop);
|
||||
|
||||
device->ExtraData = NULL;
|
||||
free(device->szDeviceName);
|
||||
device->szDeviceName = NULL;
|
||||
DestroyRingBuffer(data->ring);
|
||||
|
||||
ppa_xfree(data);
|
||||
} //}}}
|
||||
//}}}
|
||||
|
||||
// OpenAL {{{
|
||||
static ALCboolean pulse_open_playback(ALCdevice *device, const ALCchar *device_name) //{{{
|
||||
{
|
||||
if(!pa_handle)
|
||||
return ALC_FALSE;
|
||||
|
||||
if(!device_name)
|
||||
device_name = pulse_device;
|
||||
else if(strcmp(device_name, pulse_device) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
return pulse_open(device, device_name);
|
||||
} //}}}
|
||||
|
||||
static void pulse_close_playback(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_close(device);
|
||||
} //}}}
|
||||
|
||||
static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_stream_state_t state;
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
data->frame_size = aluBytesFromFormat(device->Format) *
|
||||
aluChannelsFromFormat(device->Format);
|
||||
data->attr.minreq = data->frame_size * device->UpdateSize;
|
||||
data->attr.prebuf = -1;
|
||||
data->attr.maxlength = -1;
|
||||
data->attr.fragsize = -1;
|
||||
data->attr.tlength = data->attr.minreq * device->NumUpdates;
|
||||
data->stream_name = "Playback Stream";
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
data->spec.format = PA_SAMPLE_U8;
|
||||
break;
|
||||
case 2:
|
||||
data->spec.format = PA_SAMPLE_S16NE;
|
||||
break;
|
||||
case 4:
|
||||
data->spec.format = PA_SAMPLE_FLOAT32NE;
|
||||
break;
|
||||
default:
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
data->spec.rate = device->Frequency;
|
||||
data->spec.channels = aluChannelsFromFormat(device->Format);
|
||||
|
||||
if(ppa_sample_spec_valid(&data->spec) == 0)
|
||||
{
|
||||
AL_PRINT("Invalid sample format\n");
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->stream = ppa_stream_new(data->context, data->stream_name, &data->spec, NULL);
|
||||
if(!data->stream)
|
||||
{
|
||||
AL_PRINT("pa_stream_new() failed: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(ppa_stream_connect_playback(data->stream, NULL, &data->attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0)
|
||||
{
|
||||
AL_PRINT("Stream did not connect: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_stream_unref(data->stream);
|
||||
data->stream = NULL;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
while((state=ppa_stream_get_state(data->stream)) != PA_STREAM_READY)
|
||||
{
|
||||
if(!PA_STREAM_IS_GOOD(state))
|
||||
{
|
||||
AL_PRINT("Stream did not get ready: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_stream_unref(data->stream);
|
||||
data->stream = NULL;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
Sleep(1);
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
}
|
||||
|
||||
data->attr = *(ppa_stream_get_buffer_attr(data->stream));
|
||||
if((data->attr.tlength%data->attr.minreq) != 0)
|
||||
AL_PRINT("tlength (%d) is not a multiple of minreq (%d)!\n",
|
||||
data->attr.tlength, data->attr.minreq);
|
||||
device->UpdateSize = data->attr.minreq;
|
||||
device->NumUpdates = data->attr.tlength/data->attr.minreq;
|
||||
|
||||
ppa_stream_set_write_callback(data->stream, stream_write_callback, device);
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_TRUE;
|
||||
} //}}}
|
||||
|
||||
static void pulse_stop_playback(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
|
||||
if(!data->stream)
|
||||
return;
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
ppa_stream_disconnect(data->stream);
|
||||
ppa_stream_unref(data->stream);
|
||||
data->stream = NULL;
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
} //}}}
|
||||
|
||||
|
||||
static ALCboolean pulse_open_capture(ALCdevice *device, const ALCchar *device_name) //{{{
|
||||
{
|
||||
pulse_data *data;
|
||||
pa_stream_state_t state;
|
||||
|
||||
if(!pa_handle)
|
||||
return ALC_FALSE;
|
||||
|
||||
if(!device_name)
|
||||
device_name = pulse_capture_device;
|
||||
else if(strcmp(device_name, pulse_capture_device) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
if(pulse_open(device, device_name) == ALC_FALSE)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = device->ExtraData;
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
data->samples = device->UpdateSize * device->NumUpdates;
|
||||
data->frame_size = aluBytesFromFormat(device->Format) *
|
||||
aluChannelsFromFormat(device->Format);
|
||||
|
||||
if(!(data->ring = CreateRingBuffer(data->frame_size, data->samples)))
|
||||
{
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->attr.minreq = -1;
|
||||
data->attr.prebuf = -1;
|
||||
data->attr.maxlength = -1;
|
||||
data->attr.tlength = -1;
|
||||
data->attr.fragsize = data->frame_size * data->samples / 2;
|
||||
data->stream_name = "Capture Stream";
|
||||
|
||||
data->spec.rate = device->Frequency;
|
||||
data->spec.channels = aluChannelsFromFormat(device->Format);
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
case 1:
|
||||
data->spec.format = PA_SAMPLE_U8;
|
||||
break;
|
||||
case 2:
|
||||
data->spec.format = PA_SAMPLE_S16NE;
|
||||
break;
|
||||
case 4:
|
||||
data->spec.format = PA_SAMPLE_FLOAT32NE;
|
||||
break;
|
||||
default:
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(ppa_sample_spec_valid(&data->spec) == 0)
|
||||
{
|
||||
AL_PRINT("Invalid sample format\n");
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->stream = ppa_stream_new(data->context, data->stream_name, &data->spec, NULL);
|
||||
if(!data->stream)
|
||||
{
|
||||
AL_PRINT("pa_stream_new() failed: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(ppa_stream_connect_record(data->stream, NULL, &data->attr, PA_STREAM_ADJUST_LATENCY) < 0)
|
||||
{
|
||||
AL_PRINT("Stream did not connect: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_stream_unref(data->stream);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
data->stream = NULL;
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
while((state=ppa_stream_get_state(data->stream)) != PA_STREAM_READY)
|
||||
{
|
||||
if(!PA_STREAM_IS_GOOD(state))
|
||||
{
|
||||
AL_PRINT("Stream did not get ready: %s\n",
|
||||
ppa_strerror(ppa_context_errno(data->context)));
|
||||
|
||||
ppa_stream_unref(data->stream);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
data->stream = NULL;
|
||||
pulse_close(device);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
Sleep(1);
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
}
|
||||
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_TRUE;
|
||||
} //}}}
|
||||
|
||||
static void pulse_close_capture(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_close(device);
|
||||
} //}}}
|
||||
|
||||
static void pulse_start_capture(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
ppa_stream_set_read_callback(data->stream, stream_read_callback, device);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
} //}}}
|
||||
|
||||
static void pulse_stop_capture(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
|
||||
ppa_threaded_mainloop_lock(data->loop);
|
||||
ppa_stream_set_read_callback(data->stream, NULL, NULL);
|
||||
ppa_threaded_mainloop_unlock(data->loop);
|
||||
} //}}}
|
||||
|
||||
static void pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
ALCuint available = RingBufferSize(data->ring);
|
||||
|
||||
if(available < samples)
|
||||
SetALCError(ALC_INVALID_VALUE);
|
||||
else
|
||||
ReadRingBuffer(data->ring, buffer, samples);
|
||||
} //}}}
|
||||
|
||||
static ALCuint pulse_available_samples(ALCdevice *device) //{{{
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
return RingBufferSize(data->ring);
|
||||
} //}}}
|
||||
|
||||
BackendFuncs pulse_funcs = { //{{{
|
||||
pulse_open_playback,
|
||||
pulse_close_playback,
|
||||
pulse_reset_playback,
|
||||
pulse_stop_playback,
|
||||
pulse_open_capture,
|
||||
pulse_close_capture,
|
||||
pulse_start_capture,
|
||||
pulse_stop_capture,
|
||||
pulse_capture_samples,
|
||||
pulse_available_samples
|
||||
}; //}}}
|
||||
|
||||
void alc_pulse_init(BackendFuncs *func_list) //{{{
|
||||
{
|
||||
if(func_list) *func_list = pulse_funcs;
|
||||
|
||||
#ifdef _WIN32
|
||||
pa_handle = LoadLibrary("libpulse-0.dll");
|
||||
#define LOAD_FUNC(x) do { \
|
||||
p##x = GetProcAddress(pa_handle, #x); \
|
||||
if(!(p##x)) { \
|
||||
AL_PRINT("Could not load %s from libpulse-0.dll\n", #x); \
|
||||
FreeLibrary(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#elif defined (HAVE_DLFCN_H)
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
pa_handle = dlopen("libpulse.0.dylib", RTLD_NOW);
|
||||
#else
|
||||
pa_handle = dlopen("libpulse.so.0", RTLD_NOW);
|
||||
#endif
|
||||
#define LOAD_FUNC(x) do { \
|
||||
p##x = dlsym(pa_handle, #x); \
|
||||
if(!(p##x)) { \
|
||||
AL_PRINT("Could not load %s from libpulse\n", #x); \
|
||||
dlclose(pa_handle); \
|
||||
pa_handle = NULL; \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#else
|
||||
|
||||
pa_handle = (void*)0xDEADBEEF;
|
||||
#define LOAD_FUNC(x) p##x = (x)
|
||||
|
||||
#endif
|
||||
if(!pa_handle)
|
||||
return;
|
||||
|
||||
LOAD_FUNC(pa_context_unref);
|
||||
LOAD_FUNC(pa_sample_spec_valid);
|
||||
LOAD_FUNC(pa_stream_drop);
|
||||
LOAD_FUNC(pa_strerror);
|
||||
LOAD_FUNC(pa_context_get_state);
|
||||
LOAD_FUNC(pa_stream_get_state);
|
||||
LOAD_FUNC(pa_threaded_mainloop_signal);
|
||||
LOAD_FUNC(pa_stream_peek);
|
||||
LOAD_FUNC(pa_threaded_mainloop_wait);
|
||||
LOAD_FUNC(pa_threaded_mainloop_unlock);
|
||||
LOAD_FUNC(pa_context_new);
|
||||
LOAD_FUNC(pa_threaded_mainloop_stop);
|
||||
LOAD_FUNC(pa_context_disconnect);
|
||||
LOAD_FUNC(pa_threaded_mainloop_start);
|
||||
LOAD_FUNC(pa_threaded_mainloop_get_api);
|
||||
LOAD_FUNC(pa_context_set_state_callback);
|
||||
LOAD_FUNC(pa_stream_write);
|
||||
LOAD_FUNC(pa_xfree);
|
||||
LOAD_FUNC(pa_stream_connect_record);
|
||||
LOAD_FUNC(pa_stream_connect_playback);
|
||||
LOAD_FUNC(pa_path_get_filename);
|
||||
LOAD_FUNC(pa_get_binary_name);
|
||||
LOAD_FUNC(pa_threaded_mainloop_free);
|
||||
LOAD_FUNC(pa_context_errno);
|
||||
LOAD_FUNC(pa_xmalloc0);
|
||||
LOAD_FUNC(pa_stream_unref);
|
||||
LOAD_FUNC(pa_threaded_mainloop_accept);
|
||||
LOAD_FUNC(pa_stream_set_write_callback);
|
||||
LOAD_FUNC(pa_threaded_mainloop_new);
|
||||
LOAD_FUNC(pa_context_connect);
|
||||
LOAD_FUNC(pa_stream_get_buffer_attr);
|
||||
LOAD_FUNC(pa_stream_set_read_callback);
|
||||
LOAD_FUNC(pa_stream_set_state_callback);
|
||||
LOAD_FUNC(pa_stream_new);
|
||||
LOAD_FUNC(pa_stream_disconnect);
|
||||
LOAD_FUNC(pa_threaded_mainloop_lock);
|
||||
|
||||
#undef LOAD_FUNC
|
||||
} //}}}
|
||||
|
||||
void alc_pulse_deinit(void) //{{{
|
||||
{
|
||||
if(pa_handle)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(pa_handle);
|
||||
#elif defined (HAVE_DLFCN_H)
|
||||
dlclose(pa_handle);
|
||||
#endif
|
||||
}
|
||||
pa_handle = NULL;
|
||||
} //}}}
|
||||
|
||||
void alc_pulse_probe(int type) //{{{
|
||||
{
|
||||
if(!pa_handle) alc_pulse_init(NULL);
|
||||
if(!pa_handle) return;
|
||||
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(pulse_device);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
AppendAllDeviceList(pulse_device);
|
||||
else if(type == CAPTURE_DEVICE_PROBE)
|
||||
AppendCaptureDeviceList(pulse_capture_device);
|
||||
} //}}}
|
||||
//}}}
|
||||
+92
-58
@@ -37,7 +37,7 @@
|
||||
#include <sys/audioio.h>
|
||||
|
||||
|
||||
static char *solaris_device;
|
||||
static const ALCchar solaris_device[] = "Solaris Software";
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
@@ -54,34 +54,37 @@ static ALuint SolarisProc(ALvoid *ptr)
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
solaris_data *data = (solaris_data*)pDevice->ExtraData;
|
||||
int remaining = 0;
|
||||
ALint frameSize;
|
||||
int wrote;
|
||||
|
||||
while(!data->killNow)
|
||||
frameSize = aluChannelsFromFormat(pDevice->Format) *
|
||||
aluBytesFromFormat(pDevice->Format);
|
||||
|
||||
while(!data->killNow && !pDevice->Connected)
|
||||
{
|
||||
int len = data->data_size - remaining;
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
if(len > 0)
|
||||
aluMixData(pDevice, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
aluMixData(pDevice->Context, data->mix_data+remaining, len, pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
}
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
if(wrote < 0)
|
||||
{
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK)
|
||||
{
|
||||
AL_PRINT("write failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
len = 0;
|
||||
}
|
||||
else
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
remaining += len;
|
||||
wrote = write(data->fd, data->mix_data, remaining);
|
||||
if(wrote < 0)
|
||||
{
|
||||
AL_PRINT("write failed: %s\n", strerror(errno));
|
||||
remaining = 0;
|
||||
len -= wrote;
|
||||
WritePtr += wrote;
|
||||
}
|
||||
else if(wrote > 0)
|
||||
{
|
||||
remaining -= wrote;
|
||||
if(remaining > 0)
|
||||
memmove(data->mix_data, data->mix_data+wrote, remaining);
|
||||
}
|
||||
else
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -90,22 +93,15 @@ static ALuint SolarisProc(ALvoid *ptr)
|
||||
|
||||
static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
audio_info_t info;
|
||||
ALuint frameSize;
|
||||
char driver[64];
|
||||
int numChannels;
|
||||
solaris_data *data;
|
||||
|
||||
strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1);
|
||||
driver[sizeof(driver)-1] = 0;
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, solaris_device))
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = solaris_device;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = solaris_device;
|
||||
if(!deviceName)
|
||||
deviceName = solaris_device;
|
||||
else if(strcmp(deviceName, solaris_device) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = (solaris_data*)calloc(1, sizeof(solaris_data));
|
||||
data->killNow = 0;
|
||||
@@ -118,10 +114,28 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
numChannels = aluChannelsFromFormat(device->Format);
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void solaris_close_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
|
||||
close(data->fd);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean solaris_reset_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
audio_info_t info;
|
||||
ALuint frameSize;
|
||||
int numChannels;
|
||||
|
||||
AUDIO_INITINFO(&info);
|
||||
info.play.sample_rate = device->Frequency;
|
||||
info.play.channels = numChannels;
|
||||
|
||||
switch(aluBytesFromFormat(device->Format))
|
||||
{
|
||||
@@ -129,32 +143,42 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
|
||||
info.play.precision = 8;
|
||||
info.play.encoding = AUDIO_ENCODING_LINEAR8;
|
||||
break;
|
||||
case 4:
|
||||
switch(numChannels)
|
||||
{
|
||||
case 1: device->Format = AL_FORMAT_MONO16; break;
|
||||
case 2: device->Format = AL_FORMAT_STEREO16; break;
|
||||
case 4: device->Format = AL_FORMAT_QUAD16; break;
|
||||
case 6: device->Format = AL_FORMAT_51CHN16; break;
|
||||
case 7: device->Format = AL_FORMAT_61CHN16; break;
|
||||
case 8: device->Format = AL_FORMAT_71CHN16; break;
|
||||
}
|
||||
/* fall-through */
|
||||
case 2:
|
||||
info.play.precision = 16;
|
||||
info.play.encoding = AUDIO_ENCODING_LINEAR;
|
||||
break;
|
||||
default:
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
AL_PRINT("Unknown format: 0x%x\n", device->Format);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
numChannels = aluChannelsFromFormat(device->Format);
|
||||
info.play.sample_rate = device->Frequency;
|
||||
info.play.channels = numChannels;
|
||||
|
||||
frameSize = numChannels * aluBytesFromFormat(device->Format);
|
||||
info.play.buffer_size = device->UpdateSize * frameSize;
|
||||
info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize;
|
||||
|
||||
if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0)
|
||||
{
|
||||
AL_PRINT("ioctl failed: %s\n", strerror(errno));
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->Frequency = info.play.sample_rate;
|
||||
|
||||
if(aluChannelsFromFormat(device->Format) != info.play.channels)
|
||||
{
|
||||
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), info.play.channels);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -162,40 +186,39 @@ static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *device
|
||||
(info.play.precision == 16 && aluBytesFromFormat(device->Format) == 2)))
|
||||
{
|
||||
AL_PRINT("Could not set %d-bit output, got %d\n", aluBytesFromFormat(device->Format)*8, info.play.precision);
|
||||
close(data->fd);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->UpdateSize = info.play.buffer_size / 4;
|
||||
device->Frequency = info.play.sample_rate;
|
||||
device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1;
|
||||
|
||||
data->data_size = device->UpdateSize * frameSize;
|
||||
data->mix_data = calloc(1, data->data_size);
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(SolarisProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
data->mix_data = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void solaris_close_playback(ALCdevice *device)
|
||||
static void solaris_stop_playback(ALCdevice *device)
|
||||
{
|
||||
solaris_data *data = (solaris_data*)device->ExtraData;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
|
||||
close(data->fd);
|
||||
data->thread = NULL;
|
||||
|
||||
free(data->mix_data);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
data->mix_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -241,6 +264,8 @@ static ALCuint solaris_available_samples(ALCdevice *pDevice)
|
||||
BackendFuncs solaris_funcs = {
|
||||
solaris_open_playback,
|
||||
solaris_close_playback,
|
||||
solaris_reset_playback,
|
||||
solaris_stop_playback,
|
||||
solaris_open_capture,
|
||||
solaris_close_capture,
|
||||
solaris_start_capture,
|
||||
@@ -252,7 +277,16 @@ BackendFuncs solaris_funcs = {
|
||||
void alc_solaris_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = solaris_funcs;
|
||||
|
||||
solaris_device = AppendDeviceList("Solaris Software");
|
||||
AppendAllDeviceList(solaris_device);
|
||||
}
|
||||
|
||||
void alc_solaris_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_solaris_probe(ALCboolean capture)
|
||||
{
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(solaris_device);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
AppendAllDeviceList(solaris_device);
|
||||
}
|
||||
|
||||
+67
-54
@@ -40,7 +40,7 @@ typedef struct {
|
||||
} wave_data;
|
||||
|
||||
|
||||
static ALCchar *waveDevice;
|
||||
static const ALCchar waveDevice[] = "Wave File Writer";
|
||||
|
||||
|
||||
static ALuint WaveProc(ALvoid *ptr)
|
||||
@@ -49,7 +49,7 @@ static ALuint WaveProc(ALvoid *ptr)
|
||||
wave_data *data = (wave_data*)pDevice->ExtraData;
|
||||
ALuint frameSize;
|
||||
ALuint now, last;
|
||||
size_t WriteCnt;
|
||||
size_t fs;
|
||||
ALuint avail;
|
||||
union {
|
||||
short s;
|
||||
@@ -61,43 +61,40 @@ static ALuint WaveProc(ALvoid *ptr)
|
||||
aluChannelsFromFormat(pDevice->Format);
|
||||
|
||||
last = timeGetTime();
|
||||
while(!data->killNow)
|
||||
while(!data->killNow && pDevice->Connected)
|
||||
{
|
||||
now = timeGetTime();
|
||||
|
||||
avail = (now-last) * pDevice->Frequency / 1000;
|
||||
if(avail < pDevice->UpdateSize/4)
|
||||
if(avail < pDevice->UpdateSize)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(avail > 0)
|
||||
while(avail >= pDevice->UpdateSize)
|
||||
{
|
||||
SuspendContext(NULL);
|
||||
WriteCnt = min(data->size, avail);
|
||||
aluMixData(pDevice->Context, data->buffer, WriteCnt * frameSize,
|
||||
pDevice->Format);
|
||||
ProcessContext(NULL);
|
||||
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
|
||||
|
||||
if(uSB.b[0] != 1 && aluBytesFromFormat(pDevice->Format) > 1)
|
||||
{
|
||||
ALubyte *bytes = data->buffer;
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < WriteCnt*frameSize;i++)
|
||||
for(i = 0;i < data->size;i++)
|
||||
fputc(bytes[i^1], data->f);
|
||||
}
|
||||
else
|
||||
fwrite(data->buffer, frameSize, WriteCnt, data->f);
|
||||
fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize,
|
||||
data->f);
|
||||
if(ferror(data->f))
|
||||
{
|
||||
AL_PRINT("Error writing to file\n");
|
||||
data->killNow = 1;
|
||||
aluHandleDisconnect(pDevice);
|
||||
break;
|
||||
}
|
||||
|
||||
avail -= WriteCnt;
|
||||
avail -= pDevice->UpdateSize;
|
||||
}
|
||||
last = now;
|
||||
}
|
||||
@@ -108,23 +105,16 @@ static ALuint WaveProc(ALvoid *ptr)
|
||||
static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
wave_data *data;
|
||||
ALuint channels;
|
||||
ALuint bits;
|
||||
const char *fname;
|
||||
int i;
|
||||
|
||||
fname = GetConfigValue("wave", "file", "");
|
||||
if(!fname[0])
|
||||
return ALC_FALSE;
|
||||
|
||||
if(deviceName)
|
||||
{
|
||||
if(strcmp(deviceName, waveDevice) != 0)
|
||||
return ALC_FALSE;
|
||||
device->szDeviceName = waveDevice;
|
||||
}
|
||||
else
|
||||
device->szDeviceName = waveDevice;
|
||||
if(!deviceName)
|
||||
deviceName = waveDevice;
|
||||
else if(strcmp(deviceName, waveDevice) != 0)
|
||||
return ALC_FALSE;
|
||||
|
||||
data = (wave_data*)calloc(1, sizeof(wave_data));
|
||||
|
||||
@@ -136,25 +126,44 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void wave_close_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean wave_reset_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
ALuint channels, bits, i;
|
||||
|
||||
fseek(data->f, 0, SEEK_SET);
|
||||
clearerr(data->f);
|
||||
|
||||
bits = aluBytesFromFormat(device->Format) * 8;
|
||||
channels = aluChannelsFromFormat(device->Format);
|
||||
switch(bits)
|
||||
{
|
||||
case 8:
|
||||
case 16:
|
||||
case 32:
|
||||
if(channels == 0)
|
||||
{
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
AL_PRINT("Unknown format?! %x\n", device->Format);
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -205,47 +214,45 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam
|
||||
if(ferror(data->f))
|
||||
{
|
||||
AL_PRINT("Error writing header: %s\n", strerror(errno));
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
data->DataStart = ftell(data->f);
|
||||
|
||||
device->UpdateSize = max(device->UpdateSize, 2048);
|
||||
|
||||
data->size = device->UpdateSize;
|
||||
data->buffer = malloc(data->size * channels * bits / 8);
|
||||
data->size = device->UpdateSize * channels * bits / 8;
|
||||
data->buffer = malloc(data->size);
|
||||
if(!data->buffer)
|
||||
{
|
||||
AL_PRINT("buffer malloc failed\n");
|
||||
fclose(data->f);
|
||||
free(data);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
device->ExtraData = data;
|
||||
data->thread = StartThread(WaveProc, device);
|
||||
if(data->thread == NULL)
|
||||
{
|
||||
device->ExtraData = NULL;
|
||||
fclose(data->f);
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
data->buffer = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
static void wave_close_playback(ALCdevice *device)
|
||||
static void wave_stop_playback(ALCdevice *device)
|
||||
{
|
||||
wave_data *data = (wave_data*)device->ExtraData;
|
||||
ALuint dataLen;
|
||||
long size;
|
||||
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
|
||||
size = ftell(data->f);
|
||||
if(size > 0)
|
||||
@@ -267,21 +274,13 @@ static void wave_close_playback(ALCdevice *device)
|
||||
fputc((size>>24)&0xff, data->f);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(data->f);
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
{
|
||||
(void)pDevice;
|
||||
(void)deviceName;
|
||||
(void)frequency;
|
||||
(void)format;
|
||||
(void)SampleSize;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -317,6 +316,8 @@ static ALCuint wave_available_samples(ALCdevice *pDevice)
|
||||
BackendFuncs wave_funcs = {
|
||||
wave_open_playback,
|
||||
wave_close_playback,
|
||||
wave_reset_playback,
|
||||
wave_stop_playback,
|
||||
wave_open_capture,
|
||||
wave_close_capture,
|
||||
wave_start_capture,
|
||||
@@ -328,7 +329,19 @@ BackendFuncs wave_funcs = {
|
||||
void alc_wave_init(BackendFuncs *func_list)
|
||||
{
|
||||
*func_list = wave_funcs;
|
||||
|
||||
waveDevice = AppendDeviceList("Wave File Writer");
|
||||
AppendAllDeviceList(waveDevice);
|
||||
}
|
||||
|
||||
void alc_wave_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void alc_wave_probe(int type)
|
||||
{
|
||||
if(*(GetConfigValue("wave", "file", "")) == 0)
|
||||
return;
|
||||
|
||||
if(type == DEVICE_PROBE)
|
||||
AppendDeviceList(waveDevice);
|
||||
else if(type == ALL_DEVICE_PROBE)
|
||||
AppendAllDeviceList(waveDevice);
|
||||
}
|
||||
|
||||
+44
-16
@@ -50,7 +50,8 @@ typedef struct {
|
||||
} WinMMData;
|
||||
|
||||
|
||||
static ALCchar *CaptureDeviceList[16];
|
||||
static ALCchar **CaptureDeviceList;
|
||||
static ALuint NumCaptureDevices;
|
||||
|
||||
/*
|
||||
WaveInProc
|
||||
@@ -175,20 +176,18 @@ static void WinMMClosePlayback(ALCdevice *device)
|
||||
}
|
||||
|
||||
|
||||
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei SampleSize)
|
||||
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
{
|
||||
WAVEFORMATEX wfexCaptureFormat;
|
||||
WinMMData *pData = NULL;
|
||||
ALint lDeviceID = 0;
|
||||
ALint lBufferSize;
|
||||
ALint i;
|
||||
|
||||
(void)format;
|
||||
ALuint i;
|
||||
|
||||
// Find the Device ID matching the deviceName if valid
|
||||
if (deviceName)
|
||||
{
|
||||
for(i = 0;CaptureDeviceList[i];i++)
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
{
|
||||
if (!strcmp(deviceName, CaptureDeviceList[i]))
|
||||
{
|
||||
@@ -196,10 +195,9 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!CaptureDeviceList[i])
|
||||
if(i == NumCaptureDevices)
|
||||
return ALC_FALSE;
|
||||
}
|
||||
pDevice->szDeviceName = CaptureDeviceList[lDeviceID];
|
||||
|
||||
pData = calloc(1, sizeof(*pData));
|
||||
if(!pData)
|
||||
@@ -214,7 +212,7 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
|
||||
wfexCaptureFormat.wBitsPerSample = aluBytesFromFormat(pDevice->Format) * 8;
|
||||
wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
|
||||
wfexCaptureFormat.nChannels / 8;
|
||||
wfexCaptureFormat.nSamplesPerSec = frequency;
|
||||
wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency;
|
||||
wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
|
||||
wfexCaptureFormat.nBlockAlign;
|
||||
wfexCaptureFormat.cbSize = 0;
|
||||
@@ -231,7 +229,8 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
|
||||
goto failure;
|
||||
|
||||
// Allocate circular memory buffer for the captured audio
|
||||
pData->ulCapturedDataSize = SampleSize * wfexCaptureFormat.nBlockAlign;
|
||||
pData->ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates *
|
||||
wfexCaptureFormat.nBlockAlign;
|
||||
|
||||
// Make sure circular buffer is at least 100ms in size (and an exact multiple of
|
||||
// the block alignment
|
||||
@@ -269,6 +268,7 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
|
||||
if (pData->hWaveInThread == NULL)
|
||||
goto failure;
|
||||
|
||||
pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
|
||||
return ALC_TRUE;
|
||||
|
||||
failure:
|
||||
@@ -292,6 +292,7 @@ failure:
|
||||
CloseHandle(pData->hWaveInThreadEvent);
|
||||
|
||||
free(pData);
|
||||
pDevice->ExtraData = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
@@ -413,6 +414,8 @@ static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
|
||||
BackendFuncs WinMMFuncs = {
|
||||
WinMMOpenPlayback,
|
||||
WinMMClosePlayback,
|
||||
NULL,
|
||||
NULL,
|
||||
WinMMOpenCapture,
|
||||
WinMMCloseCapture,
|
||||
WinMMStartCapture,
|
||||
@@ -423,20 +426,45 @@ BackendFuncs WinMMFuncs = {
|
||||
|
||||
void alcWinMMInit(BackendFuncs *FuncList)
|
||||
{
|
||||
ALint lNumDevs;
|
||||
ALint lLoop;
|
||||
|
||||
*FuncList = WinMMFuncs;
|
||||
}
|
||||
|
||||
lNumDevs = waveInGetNumDevs();
|
||||
for (lLoop = 0; lLoop < lNumDevs; lLoop++)
|
||||
void alcWinMMDeinit()
|
||||
{
|
||||
ALuint lLoop;
|
||||
|
||||
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
|
||||
free(CaptureDeviceList[lLoop]);
|
||||
free(CaptureDeviceList);
|
||||
CaptureDeviceList = NULL;
|
||||
|
||||
NumCaptureDevices = 0;
|
||||
}
|
||||
|
||||
void alcWinMMProbe(int type)
|
||||
{
|
||||
ALuint lLoop;
|
||||
|
||||
if(type != CAPTURE_DEVICE_PROBE)
|
||||
return;
|
||||
|
||||
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
|
||||
free(CaptureDeviceList[lLoop]);
|
||||
|
||||
NumCaptureDevices = waveInGetNumDevs();
|
||||
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
|
||||
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
|
||||
{
|
||||
WAVEINCAPS WaveInCaps;
|
||||
|
||||
if(waveInGetDevCaps(lLoop, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
|
||||
{
|
||||
char name[128];
|
||||
snprintf(name, sizeof(name), "WaveIn on %s", WaveInCaps.szPname);
|
||||
CaptureDeviceList[lLoop] = AppendCaptureDeviceList(name);
|
||||
AppendCaptureDeviceList(name);
|
||||
CaptureDeviceList[lLoop] = strdup(name);
|
||||
}
|
||||
else
|
||||
CaptureDeviceList[lLoop] = strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
+101
-31
@@ -10,6 +10,7 @@ INCLUDE(CheckFunctionExists)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
INCLUDE(CheckIncludeFile)
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckSymbolExists)
|
||||
INCLUDE(CheckCCompilerFlag)
|
||||
INCLUDE(CheckCSourceCompiles)
|
||||
INCLUDE(CheckTypeSize)
|
||||
@@ -26,6 +27,8 @@ OPTION(OSS "Check for OSS backend" ON)
|
||||
OPTION(SOLARIS "Check for Solaris backend" ON)
|
||||
OPTION(DSOUND "Check for DirectSound backend" ON)
|
||||
OPTION(WINMM "Check for Windows Multimedia backend" ON)
|
||||
OPTION(PORTAUDIO "Check for PortAudio backend" ON)
|
||||
OPTION(PULSEAUDIO "Check for PulseAudio backend" ON)
|
||||
|
||||
OPTION(DLOPEN "Check for the dlopen API for loading optional libs" ON)
|
||||
|
||||
@@ -33,22 +36,22 @@ OPTION(WERROR "Treat compile warnings as errors" OFF)
|
||||
|
||||
OPTION(EXAMPLES "Build example programs" ON)
|
||||
|
||||
OPTION(XCOMPILEWIN32 "Cross-compile to Win32" OFF)
|
||||
OPTION(ALSOFT_CONFIG "Install alsoft.conf configuration file" OFF)
|
||||
|
||||
|
||||
IF(WIN32 OR XCOMPILEWIN32)
|
||||
SET(LIBNAME openal32)
|
||||
IF(WIN32)
|
||||
SET(LIBNAME OpenAL32)
|
||||
ADD_DEFINITIONS("-D_WIN32")
|
||||
ELSE()
|
||||
SET(LIBNAME openal)
|
||||
ENDIF()
|
||||
|
||||
SET(LIB_MAJOR_VERSION "1")
|
||||
SET(LIB_MINOR_VERSION "6")
|
||||
SET(LIB_BUILD_VERSION "372")
|
||||
SET(LIB_MINOR_VERSION "9")
|
||||
SET(LIB_BUILD_VERSION "563")
|
||||
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}")
|
||||
IF(NOT DEFINED LIB_INSTALL_DIR)
|
||||
SET(LIB_INSTALL_DIR "lib")
|
||||
SET(LIB_INSTALL_DIR "lib${LIB_SUFFIX}")
|
||||
ENDIF(NOT DEFINED LIB_INSTALL_DIR)
|
||||
|
||||
|
||||
@@ -66,6 +69,11 @@ IF(NOT CMAKE_BUILD_TYPE)
|
||||
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
|
||||
FORCE)
|
||||
ENDIF()
|
||||
IF(NOT CMAKE_DEBUG_POSTFIX)
|
||||
SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING
|
||||
"Library postfix for debug builds. Normally left blank."
|
||||
FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF(MSVC)
|
||||
# ???
|
||||
@@ -73,10 +81,11 @@ IF(MSVC)
|
||||
SET(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -DNDEBUG")
|
||||
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNDEBUG")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
|
||||
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
|
||||
ELSE()
|
||||
ADD_DEFINITIONS(-Wall)
|
||||
CHECK_C_COMPILER_FLAG(-Wextra HAVE_W_EXTRA)
|
||||
IF("${HAVE_W_EXTRA}")
|
||||
IF(HAVE_W_EXTRA)
|
||||
ADD_DEFINITIONS(-Wextra)
|
||||
ENDIF()
|
||||
|
||||
@@ -98,15 +107,15 @@ ELSE()
|
||||
FORCE)
|
||||
|
||||
# Set visibility options if available
|
||||
IF(NOT WIN32 AND NOT XCOMPILEWIN32)
|
||||
IF(NOT WIN32)
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((destructor));
|
||||
int main() {return 0;}" HAVE_GCC_DESTRUCTOR)
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_VISIBILITY_SWITCH)
|
||||
IF("${HAVE_VISIBILITY_SWITCH}")
|
||||
IF(HAVE_VISIBILITY_SWITCH)
|
||||
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((visibility(\"default\")));
|
||||
int main() {return 0;}" HAVE_GCC_VISIBILITY)
|
||||
IF("${HAVE_GCC_VISIBILITY}")
|
||||
IF(HAVE_GCC_VISIBILITY)
|
||||
ADD_DEFINITIONS(-fvisibility=hidden -DHAVE_GCC_VISIBILITY)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -118,10 +127,12 @@ CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
|
||||
|
||||
CHECK_LIBRARY_EXISTS(m sqrtf "" HAVE_SQRTF)
|
||||
CHECK_LIBRARY_EXISTS(m acosf "" HAVE_ACOSF)
|
||||
CHECK_LIBRARY_EXISTS(m atanf "" HAVE_ATANF)
|
||||
CHECK_LIBRARY_EXISTS(m fabsf "" HAVE_FABSF)
|
||||
IF(HAVE_FENV_H)
|
||||
CHECK_LIBRARY_EXISTS(m fesetround "" HAVE_FESETROUND)
|
||||
ENDIF()
|
||||
IF(HAVE_SQRTF OR HAVE_ACOSF OR HAVE_FESETROUND)
|
||||
IF(HAVE_SQRTF OR HAVE_ACOSF OR HAVE_ATANF OR HAVE_FABSF OR HAVE_FESETROUND)
|
||||
SET(EXTRA_LIBS m ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF)
|
||||
@@ -157,6 +168,27 @@ IF(NOT HAVE_SNPRINTF)
|
||||
ADD_DEFINITIONS(-Dsnprintf=_snprintf)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(vsnprintf HAVE_VSNPRINTF)
|
||||
IF(NOT HAVE_VSNPRINTF)
|
||||
CHECK_FUNCTION_EXISTS(_vsnprintf HAVE__VSNPRINTF)
|
||||
IF(NOT HAVE__VSNPRINTF)
|
||||
MESSAGE(FATAL_ERROR "No vsnprintf function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Dvsnprintf=_vsnprintf)
|
||||
ENDIF()
|
||||
|
||||
CHECK_SYMBOL_EXISTS(isnan math.h HAVE_ISNAN)
|
||||
IF(NOT HAVE_ISNAN)
|
||||
CHECK_FUNCTION_EXISTS(_isnan HAVE__ISNAN)
|
||||
IF(NOT HAVE__ISNAN)
|
||||
MESSAGE(FATAL_ERROR "No isnan function found, please report!")
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-Disnan=_isnan)
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Check for the dlopen API (for dynamicly loading backend libs)
|
||||
IF(DLOPEN)
|
||||
CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
|
||||
@@ -220,6 +252,7 @@ ENDIF()
|
||||
|
||||
SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
|
||||
OpenAL32/alBuffer.c
|
||||
OpenAL32/alDatabuffer.c
|
||||
OpenAL32/alEffect.c
|
||||
OpenAL32/alError.c
|
||||
OpenAL32/alExtension.c
|
||||
@@ -232,6 +265,7 @@ SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
|
||||
SET(ALC_OBJS Alc/ALc.c
|
||||
Alc/ALu.c
|
||||
Alc/alcConfig.c
|
||||
Alc/alcEcho.c
|
||||
Alc/alcReverb.c
|
||||
Alc/alcRing.c
|
||||
Alc/alcThread.c
|
||||
@@ -283,16 +317,17 @@ ENDIF()
|
||||
IF(DSOUND)
|
||||
CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H)
|
||||
IF(HAVE_DSOUND_H)
|
||||
SET(HAVE_DSOUND 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
|
||||
SET(BACKENDS "${BACKENDS} DirectSound,")
|
||||
CHECK_LIBRARY_EXISTS(dsound DirectSoundCreate "" HAVE_LIBDSOUND)
|
||||
IF(HAVE_LIBDSOUND OR WIN32)
|
||||
SET(HAVE_DSOUND 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
|
||||
|
||||
SET(CMAKE_REQUIRED_LIBRARIES dsound)
|
||||
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" HAVE_LIBDSOUND)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES "")
|
||||
# CHECK_LIBRARY_EXISTS(dsound DirectSoundCreate "" HAVE_LIBDSOUND)
|
||||
IF(HAVE_LIBDSOUND)
|
||||
SET(EXTRA_LIBS dsound ${EXTRA_LIBS})
|
||||
IF(WIN32)
|
||||
SET(BACKENDS "${BACKENDS} DirectSound,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} DirectSound \(linked\),")
|
||||
SET(EXTRA_LIBS dsound ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -315,6 +350,42 @@ IF(HAVE_WINDOWS_H)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Check PortAudio backend
|
||||
IF(PORTAUDIO)
|
||||
CHECK_INCLUDE_FILE(portaudio.h HAVE_PORTAUDIO_H)
|
||||
IF(HAVE_PORTAUDIO_H)
|
||||
CHECK_LIBRARY_EXISTS(portaudio Pa_Initialize "" HAVE_LIBPORTAUDIO)
|
||||
IF(HAVE_LIBPORTAUDIO)
|
||||
SET(HAVE_PORTAUDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/portaudio.c)
|
||||
IF(HAVE_DLFCN_H)
|
||||
SET(BACKENDS "${BACKENDS} PortAudio,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} PortAudio \(linked\),")
|
||||
SET(EXTRA_LIBS portaudio ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Check PortAudio backend
|
||||
IF(PULSEAUDIO)
|
||||
CHECK_INCLUDE_FILE(pulse/pulseaudio.h HAVE_PULSE_PULSEAUDIO_H)
|
||||
IF(HAVE_PULSE_PULSEAUDIO_H)
|
||||
CHECK_LIBRARY_EXISTS(pulse pa_context_new "" HAVE_LIBPULSE)
|
||||
IF(HAVE_LIBPULSE)
|
||||
SET(HAVE_PULSEAUDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/pulseaudio.c)
|
||||
IF(HAVE_DLFCN_H)
|
||||
SET(BACKENDS "${BACKENDS} PulseAudio,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} PulseAudio \(linked\),")
|
||||
SET(EXTRA_LIBS pulse ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# This is always available
|
||||
SET(BACKENDS "${BACKENDS} WaveFile")
|
||||
|
||||
@@ -347,15 +418,6 @@ SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION}
|
||||
IF(WIN32)
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "")
|
||||
ENDIF()
|
||||
IF(XCOMPILEWIN32)
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "" SUFFIX .dll)
|
||||
IF(EXAMPLES)
|
||||
SET(EXAMPLES OFF)
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Building examples disabled when cross-compiling")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES OUTPUT_NAME ${LIBNAME})
|
||||
|
||||
TARGET_LINK_LIBRARIES(${LIBNAME} ${EXTRA_LIBS})
|
||||
|
||||
@@ -371,7 +433,15 @@ INSTALL(FILES include/AL/al.h
|
||||
DESTINATION include/AL
|
||||
)
|
||||
INSTALL(FILES "${OpenAL_BINARY_DIR}/admin/pkgconfig/openal.pc"
|
||||
DESTINATION lib/pkgconfig)
|
||||
DESTINATION "${LIB_INSTALL_DIR}/pkgconfig")
|
||||
|
||||
# Install alsoft.conf configuration file
|
||||
IF(ALSOFT_CONFIG)
|
||||
INSTALL(FILES alsoftrc.sample
|
||||
DESTINATION /etc/openal
|
||||
RENAME alsoft.conf
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(EXAMPLES)
|
||||
ADD_EXECUTABLE(openal-info examples/openal-info.c)
|
||||
@@ -388,7 +458,7 @@ MESSAGE(STATUS "Building OpenAL with support for the following backends:")
|
||||
MESSAGE(STATUS " ${BACKENDS}")
|
||||
MESSAGE(STATUS "")
|
||||
|
||||
IF(WIN32 OR XCOMPILEWIN32)
|
||||
IF(WIN32)
|
||||
IF(NOT HAVE_DSOUND)
|
||||
MESSAGE(STATUS "WARNING: Building the Windows version without DirectSound output")
|
||||
MESSAGE(STATUS " This is probably NOT what you want!")
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "AL/al.h"
|
||||
#include "alEffect.h"
|
||||
#include "alFilter.h"
|
||||
#include "alReverb.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -16,6 +15,8 @@ extern "C" {
|
||||
|
||||
#define AL_EFFECTSLOT_NULL 0x0000
|
||||
|
||||
typedef struct ALeffectState ALeffectState;
|
||||
|
||||
typedef struct ALeffectslot
|
||||
{
|
||||
ALeffect effect;
|
||||
@@ -23,7 +24,9 @@ typedef struct ALeffectslot
|
||||
ALfloat Gain;
|
||||
ALboolean AuxSendAuto;
|
||||
|
||||
ALverbState *ReverbState;
|
||||
ALeffectState *EffectState;
|
||||
|
||||
ALfloat WetBuffer[BUFFERSIZE];
|
||||
|
||||
ALuint refcount;
|
||||
|
||||
@@ -49,6 +52,22 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
|
||||
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
||||
|
||||
|
||||
struct ALeffectState {
|
||||
ALvoid (*Destroy)(ALeffectState *State);
|
||||
ALvoid (*Update)(ALeffectState *State, ALCcontext *Context, ALeffect *Effect);
|
||||
ALvoid (*Process)(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
};
|
||||
|
||||
ALeffectState *EAXVerbCreate(ALCcontext *Context);
|
||||
ALeffectState *VerbCreate(ALCcontext *Context);
|
||||
ALeffectState *EchoCreate(ALCcontext *Context);
|
||||
|
||||
#define ALEffect_Destroy(a) ((a)->Destroy((a)))
|
||||
#define ALEffect_Update(a,b,c) ((a)->Update((a),(b),(c)))
|
||||
#define ALEffect_Process(a,b,c,d,e) ((a)->Process((a),(b),(c),(d),(e)))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@ extern "C" {
|
||||
#define PENDING 1
|
||||
#define PROCESSED 2
|
||||
|
||||
typedef struct ALbuffer_struct
|
||||
typedef struct ALbuffer
|
||||
{
|
||||
ALenum format;
|
||||
ALenum eOriginalFormat;
|
||||
@@ -21,12 +21,12 @@ typedef struct ALbuffer_struct
|
||||
ALsizei padding;
|
||||
ALenum state;
|
||||
ALuint refcount; // Number of sources using this buffer (deletion can only occur when this is 0)
|
||||
struct ALbuffer_struct *next;
|
||||
struct ALbuffer *next;
|
||||
} ALbuffer;
|
||||
|
||||
ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
|
||||
|
||||
ALvoid ReleaseALBuffers(ALvoid);
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef _AL_DATABUFFER_H_
|
||||
#define _AL_DATABUFFER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UNMAPPED 0
|
||||
#define MAPPED 1
|
||||
|
||||
typedef struct ALdatabuffer
|
||||
{
|
||||
ALubyte *data;
|
||||
ALuint size;
|
||||
ALenum state;
|
||||
|
||||
ALenum usage;
|
||||
|
||||
/* Index to self */
|
||||
ALuint databuffer;
|
||||
|
||||
struct ALdatabuffer *next;
|
||||
} ALdatabuffer;
|
||||
|
||||
ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers);
|
||||
ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers);
|
||||
ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer);
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
|
||||
ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, const ALvoid *data);
|
||||
ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, ALvoid *data);
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue);
|
||||
ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues);
|
||||
ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue);
|
||||
ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues);
|
||||
ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue);
|
||||
ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues);
|
||||
ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue);
|
||||
ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues);
|
||||
|
||||
ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer);
|
||||
|
||||
ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
|
||||
ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer);
|
||||
|
||||
ALvoid ReleaseALDatabuffers(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+184
-6
@@ -1,3 +1,5 @@
|
||||
// NOTE: The effect structure is getting too large, it may be a good idea to
|
||||
// start using a union or another form of unified storage.
|
||||
#ifndef _AL_EFFECT_H_
|
||||
#define _AL_EFFECT_H_
|
||||
|
||||
@@ -22,6 +24,7 @@ extern "C" {
|
||||
#define AL_EFFECT_AUTOWAH 0x000A
|
||||
#define AL_EFFECT_COMPRESSOR 0x000B
|
||||
#define AL_EFFECT_EQUALIZER 0x000C
|
||||
#define AL_EFFECT_EAXREVERB 0x8000
|
||||
|
||||
#define AL_REVERB_DENSITY 0x0001
|
||||
#define AL_REVERB_DIFFUSION 0x0002
|
||||
@@ -37,23 +40,176 @@ extern "C" {
|
||||
#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
|
||||
#define AL_REVERB_DECAY_HFLIMIT 0x000D
|
||||
|
||||
#define AL_REVERB_MIN_DENSITY (0.0f)
|
||||
#define AL_REVERB_MAX_DENSITY (1.0f)
|
||||
#define AL_REVERB_DEFAULT_DENSITY (1.0f)
|
||||
#define AL_REVERB_MIN_DIFFUSION (0.0f)
|
||||
#define AL_REVERB_MAX_DIFFUSION (1.0f)
|
||||
#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
|
||||
#define AL_REVERB_MIN_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_GAIN (1.0f)
|
||||
#define AL_REVERB_DEFAULT_GAIN (0.32f)
|
||||
#define AL_REVERB_MIN_GAINHF (0.0f)
|
||||
#define AL_REVERB_MAX_GAINHF (1.0f)
|
||||
#define AL_REVERB_DEFAULT_GAINHF (0.89f)
|
||||
#define AL_REVERB_MIN_DECAY_TIME (0.1f)
|
||||
#define AL_REVERB_MAX_DECAY_TIME (20.0f)
|
||||
#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
|
||||
#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
|
||||
#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
|
||||
#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
|
||||
#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
|
||||
#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
|
||||
#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
|
||||
#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
|
||||
#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
|
||||
#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
|
||||
#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
|
||||
#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
|
||||
#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
|
||||
#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
|
||||
#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
|
||||
#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
|
||||
#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
|
||||
#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
|
||||
#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
|
||||
#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_REVERB_MIN_DECAY_HFLIMIT (AL_FALSE)
|
||||
#define AL_REVERB_MAX_DECAY_HFLIMIT (AL_TRUE)
|
||||
#define AL_REVERB_DEFAULT_DECAY_HFLIMIT (AL_TRUE)
|
||||
|
||||
#define AL_ECHO_DELAY 0x0001
|
||||
#define AL_ECHO_LRDELAY 0x0002
|
||||
#define AL_ECHO_DAMPING 0x0003
|
||||
#define AL_ECHO_FEEDBACK 0x0004
|
||||
#define AL_ECHO_SPREAD 0x0005
|
||||
|
||||
#define AL_ECHO_MIN_DELAY (0.0f)
|
||||
#define AL_ECHO_MAX_DELAY (0.207f)
|
||||
#define AL_ECHO_DEFAULT_DELAY (0.1f)
|
||||
#define AL_ECHO_MIN_LRDELAY (0.0f)
|
||||
#define AL_ECHO_MAX_LRDELAY (0.404f)
|
||||
#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
|
||||
#define AL_ECHO_MIN_DAMPING (0.0f)
|
||||
#define AL_ECHO_MAX_DAMPING (0.99f)
|
||||
#define AL_ECHO_DEFAULT_DAMPING (0.5f)
|
||||
#define AL_ECHO_MIN_FEEDBACK (0.0f)
|
||||
#define AL_ECHO_MAX_FEEDBACK (1.0f)
|
||||
#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
|
||||
#define AL_ECHO_MIN_SPREAD (-1.0f)
|
||||
#define AL_ECHO_MAX_SPREAD (1.0f)
|
||||
#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
|
||||
|
||||
#define AL_EAXREVERB_DENSITY 0x0001
|
||||
#define AL_EAXREVERB_DIFFUSION 0x0002
|
||||
#define AL_EAXREVERB_GAIN 0x0003
|
||||
#define AL_EAXREVERB_GAINHF 0x0004
|
||||
#define AL_EAXREVERB_GAINLF 0x0005
|
||||
#define AL_EAXREVERB_DECAY_TIME 0x0006
|
||||
#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
|
||||
#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
|
||||
#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
|
||||
#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
|
||||
#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
|
||||
#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
|
||||
#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
|
||||
#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
|
||||
#define AL_EAXREVERB_ECHO_TIME 0x000F
|
||||
#define AL_EAXREVERB_ECHO_DEPTH 0x0010
|
||||
#define AL_EAXREVERB_MODULATION_TIME 0x0011
|
||||
#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
|
||||
#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
|
||||
#define AL_EAXREVERB_HFREFERENCE 0x0014
|
||||
#define AL_EAXREVERB_LFREFERENCE 0x0015
|
||||
#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
|
||||
#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
|
||||
|
||||
#define AL_EAXREVERB_MIN_DENSITY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_DENSITY (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
|
||||
#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
|
||||
#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
|
||||
#define AL_EAXREVERB_MIN_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAIN (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
|
||||
#define AL_EAXREVERB_MIN_GAINHF (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAINHF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
|
||||
#define AL_EAXREVERB_MIN_GAINLF (0.0f)
|
||||
#define AL_EAXREVERB_MAX_GAINLF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
|
||||
#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
|
||||
#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
|
||||
#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
|
||||
#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
|
||||
#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
|
||||
#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
|
||||
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
|
||||
#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
|
||||
#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
|
||||
#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
|
||||
#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
|
||||
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
|
||||
#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
|
||||
#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
|
||||
#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
|
||||
#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
|
||||
#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
|
||||
#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
|
||||
#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
|
||||
#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
|
||||
#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
|
||||
#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
|
||||
#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
|
||||
#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
|
||||
#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
|
||||
#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
|
||||
#define AL_EAXREVERB_MIN_DECAY_HFLIMIT (AL_FALSE)
|
||||
#define AL_EAXREVERB_MAX_DECAY_HFLIMIT (AL_TRUE)
|
||||
#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT (AL_TRUE)
|
||||
|
||||
enum {
|
||||
REVERB = 0,
|
||||
EAXREVERB = 0,
|
||||
REVERB,
|
||||
ECHO,
|
||||
|
||||
MAX_EFFECTS
|
||||
};
|
||||
extern ALboolean DisabledEffects[MAX_EFFECTS];
|
||||
|
||||
|
||||
typedef struct ALeffect_struct
|
||||
typedef struct ALeffect
|
||||
{
|
||||
// Effect type (AL_EFFECT_NULL, ...)
|
||||
ALenum type;
|
||||
|
||||
struct {
|
||||
// Shared Reverb Properties
|
||||
ALfloat Density;
|
||||
ALfloat Diffusion;
|
||||
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
ALfloat DecayTime;
|
||||
@@ -65,12 +221,34 @@ typedef struct ALeffect_struct
|
||||
ALfloat AirAbsorptionGainHF;
|
||||
ALfloat RoomRolloffFactor;
|
||||
ALboolean DecayHFLimit;
|
||||
|
||||
// Additional EAX Reverb Properties
|
||||
ALfloat GainLF;
|
||||
ALfloat DecayLFRatio;
|
||||
ALfloat ReflectionsPan[3];
|
||||
ALfloat LateReverbPan[3];
|
||||
ALfloat EchoTime;
|
||||
ALfloat EchoDepth;
|
||||
ALfloat ModulationTime;
|
||||
ALfloat ModulationDepth;
|
||||
ALfloat HFReference;
|
||||
ALfloat LFReference;
|
||||
} Reverb;
|
||||
|
||||
struct {
|
||||
ALfloat Delay;
|
||||
ALfloat LRDelay;
|
||||
|
||||
ALfloat Damping;
|
||||
ALfloat Feedback;
|
||||
|
||||
ALfloat Spread;
|
||||
} Echo;
|
||||
|
||||
// Index to itself
|
||||
ALuint effect;
|
||||
|
||||
struct ALeffect_struct *next;
|
||||
struct ALeffect *next;
|
||||
} ALeffect;
|
||||
|
||||
ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
|
||||
@@ -87,7 +265,7 @@ ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
|
||||
ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
|
||||
ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
|
||||
|
||||
ALvoid ReleaseALEffects(ALvoid);
|
||||
ALvoid ReleaseALEffects(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -2,16 +2,54 @@
|
||||
#define _AL_FILTER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
ALfloat history[4];
|
||||
ALfloat coeff;
|
||||
#ifndef _MSC_VER
|
||||
ALfloat history[0];
|
||||
#else
|
||||
ALfloat history[1];
|
||||
#endif
|
||||
} FILTER;
|
||||
|
||||
static __inline ALfloat lpFilter4P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
ALfloat *history = &iir->history[offset];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
history[0] = output;
|
||||
output = output + (history[1]-output)*a;
|
||||
history[1] = output;
|
||||
output = output + (history[2]-output)*a;
|
||||
history[2] = output;
|
||||
output = output + (history[3]-output)*a;
|
||||
history[3] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
ALfloat *history = &iir->history[offset];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
history[0] = output;
|
||||
output = output + (history[1]-output)*a;
|
||||
history[1] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
#define AL_FILTER_TYPE 0x8001
|
||||
|
||||
#define AL_FILTER_NULL 0x0000
|
||||
@@ -23,7 +61,7 @@ typedef struct {
|
||||
#define AL_LOWPASS_GAINHF 0x0002
|
||||
|
||||
|
||||
typedef struct ALfilter_struct
|
||||
typedef struct ALfilter
|
||||
{
|
||||
// Filter type (AL_FILTER_NULL, ...)
|
||||
ALenum type;
|
||||
@@ -34,7 +72,7 @@ typedef struct ALfilter_struct
|
||||
// Index to itself
|
||||
ALuint filter;
|
||||
|
||||
struct ALfilter_struct *next;
|
||||
struct ALfilter *next;
|
||||
} ALfilter;
|
||||
|
||||
ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
|
||||
@@ -51,7 +89,7 @@ ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
|
||||
ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
|
||||
ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
|
||||
|
||||
ALvoid ReleaseALFilters(ALvoid);
|
||||
ALvoid ReleaseALFilters(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+118
-26
@@ -3,13 +3,16 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "alu.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
@@ -17,6 +20,12 @@
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef DWORD tls_type;
|
||||
#define tls_create(x) (*(x) = TlsAlloc())
|
||||
#define tls_delete(x) TlsFree((x))
|
||||
#define tls_get(x) TlsGetValue((x))
|
||||
#define tls_set(x, a) TlsSetValue((x), (a))
|
||||
|
||||
#else
|
||||
|
||||
#include <assert.h>
|
||||
@@ -30,6 +39,12 @@
|
||||
|
||||
#define IsBadWritePtr(a,b) (0)
|
||||
|
||||
typedef pthread_key_t tls_type;
|
||||
#define tls_create(x) pthread_key_create((x), NULL)
|
||||
#define tls_delete(x) pthread_key_delete((x))
|
||||
#define tls_get(x) pthread_getspecific((x))
|
||||
#define tls_set(x, a) pthread_setspecific((x), (a))
|
||||
|
||||
typedef pthread_mutex_t CRITICAL_SECTION;
|
||||
static inline void EnterCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
@@ -98,28 +113,37 @@ static inline void Sleep(ALuint t)
|
||||
#define max(x,y) (((x)>(y))?(x):(y))
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "alListener.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char _alDebug[256];
|
||||
static __inline void al_print(const char *fname, unsigned int line, const char *fmt, ...)
|
||||
{
|
||||
const char *fn;
|
||||
char str[256];
|
||||
int i;
|
||||
|
||||
#define AL_PRINT(...) do { \
|
||||
int _al_print_i; \
|
||||
const char *_al_print_fn = strrchr(__FILE__, '/'); \
|
||||
if(!_al_print_fn) _al_print_fn = __FILE__; \
|
||||
else _al_print_fn += 1; \
|
||||
_al_print_i = snprintf(_alDebug, sizeof(_alDebug), "AL lib: %s:%d: ", _al_print_fn, __LINE__); \
|
||||
if(_al_print_i < (int)sizeof(_alDebug) && _al_print_i > 0) \
|
||||
snprintf(_alDebug+_al_print_i, sizeof(_alDebug)-_al_print_i, __VA_ARGS__); \
|
||||
_alDebug[sizeof(_alDebug)-1] = 0; \
|
||||
fprintf(stderr, "%s", _alDebug); \
|
||||
} while(0)
|
||||
fn = strrchr(fname, '/');
|
||||
if(!fn) fn = strrchr(fname, '\\');;
|
||||
if(!fn) fn = fname;
|
||||
else fn += 1;
|
||||
|
||||
i = snprintf(str, sizeof(str), "AL lib: %s:%d: ", fn, line);
|
||||
if(i < (int)sizeof(str) && i > 0)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(str+i, sizeof(str)-i, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
str[sizeof(str)-1] = 0;
|
||||
|
||||
fprintf(stderr, "%s", str);
|
||||
}
|
||||
#define AL_PRINT(...) al_print(__FILE__, __LINE__, __VA_ARGS__)
|
||||
|
||||
|
||||
#define SWMIXER_OUTPUT_RATE 44100
|
||||
@@ -129,12 +153,17 @@ extern char _alDebug[256];
|
||||
|
||||
#define LOWPASSFREQCUTOFF (5000)
|
||||
|
||||
#define QUADRANT_NUM 128
|
||||
#define LUT_NUM (4 * QUADRANT_NUM)
|
||||
|
||||
|
||||
typedef struct {
|
||||
ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*);
|
||||
void (*ClosePlayback)(ALCdevice*);
|
||||
ALCboolean (*ResetPlayback)(ALCdevice*);
|
||||
void (*StopPlayback)(ALCdevice*);
|
||||
|
||||
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*, ALCuint, ALCenum, ALCsizei);
|
||||
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*);
|
||||
void (*CloseCapture)(ALCdevice*);
|
||||
void (*StartCapture)(ALCdevice*);
|
||||
void (*StopCapture)(ALCdevice*);
|
||||
@@ -142,26 +171,78 @@ typedef struct {
|
||||
ALCuint (*AvailableSamples)(ALCdevice*);
|
||||
} BackendFuncs;
|
||||
|
||||
enum {
|
||||
DEVICE_PROBE,
|
||||
ALL_DEVICE_PROBE,
|
||||
CAPTURE_DEVICE_PROBE
|
||||
};
|
||||
|
||||
void alc_alsa_init(BackendFuncs *func_list);
|
||||
void alc_alsa_deinit(void);
|
||||
void alc_alsa_probe(int type);
|
||||
void alc_oss_init(BackendFuncs *func_list);
|
||||
void alc_oss_deinit(void);
|
||||
void alc_oss_probe(int type);
|
||||
void alc_solaris_init(BackendFuncs *func_list);
|
||||
void alc_solaris_deinit(void);
|
||||
void alc_solarise_probe(int type);
|
||||
void alcDSoundInit(BackendFuncs *func_list);
|
||||
void alcDSoundDeinit(void);
|
||||
void alcDSoundProbe(int type);
|
||||
void alcWinMMInit(BackendFuncs *FuncList);
|
||||
void alcWinMMDeinit(void);
|
||||
void alcWinMMProbe(int type);
|
||||
void alc_pa_init(BackendFuncs *func_list);
|
||||
void alc_pa_deinit(void);
|
||||
void alc_pa_probe(int type);
|
||||
void alc_wave_init(BackendFuncs *func_list);
|
||||
void alc_wave_deinit(void);
|
||||
void alc_wave_probe(int type);
|
||||
void alc_pulse_init(BackendFuncs *func_list);
|
||||
void alc_pulse_deinit(void);
|
||||
void alc_pulse_probe(int type);
|
||||
|
||||
|
||||
struct ALCdevice_struct
|
||||
{
|
||||
ALCboolean Connected;
|
||||
ALboolean IsCaptureDevice;
|
||||
|
||||
ALuint Frequency;
|
||||
ALuint UpdateSize;
|
||||
ALuint NumUpdates;
|
||||
ALenum Format;
|
||||
|
||||
ALCchar *szDeviceName;
|
||||
|
||||
// Maximum number of sources that can be created
|
||||
ALuint MaxNoOfSources;
|
||||
// Maximum number of slots that can be created
|
||||
ALuint AuxiliaryEffectSlotMax;
|
||||
|
||||
ALint lNumMonoSources;
|
||||
ALint lNumStereoSources;
|
||||
ALuint NumAuxSends;
|
||||
|
||||
// Linked List of Buffers for this device
|
||||
struct ALbuffer *Buffers;
|
||||
ALuint BufferCount;
|
||||
|
||||
// Linked List of Effects for this device
|
||||
struct ALeffect *EffectList;
|
||||
ALuint EffectCount;
|
||||
|
||||
// Linked List of Filters for this device
|
||||
struct ALfilter *FilterList;
|
||||
ALuint FilterCount;
|
||||
|
||||
// Linked List of Databuffers for this device
|
||||
struct ALdatabuffer *Databuffers;
|
||||
ALuint DatabufferCount;
|
||||
|
||||
// Stereo-to-binaural filter
|
||||
struct bs2b *Bs2b;
|
||||
ALCint Bs2bLevel;
|
||||
|
||||
// Context created on this device
|
||||
ALCcontext *Context;
|
||||
@@ -174,7 +255,9 @@ struct ALCdevice_struct
|
||||
|
||||
#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b)))
|
||||
#define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a)))
|
||||
#define ALCdevice_OpenCapture(a,b,c,d,e) ((a)->Funcs->OpenCapture((a), (b), (c), (d), (e)))
|
||||
#define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a)))
|
||||
#define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a)))
|
||||
#define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b)))
|
||||
#define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a)))
|
||||
#define ALCdevice_StartCapture(a) ((a)->Funcs->StartCapture((a)))
|
||||
#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
|
||||
@@ -191,6 +274,9 @@ struct ALCcontext_struct
|
||||
struct ALeffectslot *AuxiliaryEffectSlot;
|
||||
ALuint AuxiliaryEffectSlotCount;
|
||||
|
||||
struct ALdatabuffer *SampleSource;
|
||||
struct ALdatabuffer *SampleSink;
|
||||
|
||||
ALenum LastError;
|
||||
ALboolean InUse;
|
||||
|
||||
@@ -202,22 +288,22 @@ struct ALCcontext_struct
|
||||
ALfloat DopplerVelocity;
|
||||
ALfloat flSpeedOfSound;
|
||||
|
||||
ALint lNumMonoSources;
|
||||
ALint lNumStereoSources;
|
||||
ALfloat PanningLUT[OUTPUTCHANNELS * LUT_NUM];
|
||||
ALint NumChan;
|
||||
|
||||
ALfloat ChannelMatrix[OUTPUTCHANNELS][OUTPUTCHANNELS];
|
||||
|
||||
ALCdevice *Device;
|
||||
const ALCchar *ExtensionList;
|
||||
|
||||
struct bs2b *bs2b;
|
||||
|
||||
ALCcontext *next;
|
||||
};
|
||||
|
||||
ALCvoid ReleaseALC(ALCvoid);
|
||||
|
||||
ALCchar *AppendDeviceList(char *name);
|
||||
ALCchar *AppendAllDeviceList(char *name);
|
||||
ALCchar *AppendCaptureDeviceList(char *name);
|
||||
void AppendDeviceList(const ALCchar *name);
|
||||
void AppendAllDeviceList(const ALCchar *name);
|
||||
void AppendCaptureDeviceList(const ALCchar *name);
|
||||
|
||||
ALCvoid SetALCError(ALenum errorCode);
|
||||
|
||||
@@ -227,6 +313,8 @@ ALCvoid ProcessContext(ALCcontext *context);
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
|
||||
ALuint StopThread(ALvoid *thread);
|
||||
|
||||
ALCcontext *GetContextSuspended(void);
|
||||
|
||||
typedef struct RingBuffer RingBuffer;
|
||||
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
|
||||
void DestroyRingBuffer(RingBuffer *ring);
|
||||
@@ -239,6 +327,10 @@ void FreeALConfig(void);
|
||||
const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
|
||||
int GetConfigValueInt(const char *blockName, const char *keyName, int def);
|
||||
float GetConfigValueFloat(const char *blockName, const char *keyName, float def);
|
||||
int GetConfigValueBool(const char *blockName, const char *keyName, float def);
|
||||
|
||||
ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context);
|
||||
ALCcontext* ALCAPIENTRY alcGetThreadContext(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#ifndef _AL_REVERB_H_
|
||||
#define _AL_REVERB_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alEffect.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALverbState ALverbState;
|
||||
|
||||
ALverbState *VerbCreate(ALCcontext *Context);
|
||||
ALvoid VerbDestroy(ALverbState *State);
|
||||
ALvoid VerbUpdate(ALCcontext *Context, struct ALeffectslot *Slot, ALeffect *Effect);
|
||||
ALvoid VerbProcess(ALverbState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[OUTPUTCHANNELS]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#define AL_NUM_SOURCE_PARAMS 128
|
||||
|
||||
/* This cannot be changed without working on the code! */
|
||||
#define MAX_SENDS 1
|
||||
#define MAX_SENDS 2
|
||||
|
||||
#include "alFilter.h"
|
||||
#include "alu.h"
|
||||
@@ -48,6 +47,7 @@ typedef struct ALsource
|
||||
ALfloat vOrientation[3];
|
||||
ALboolean bHeadRelative;
|
||||
ALboolean bLooping;
|
||||
ALenum DistanceModel;
|
||||
|
||||
ALuint ulBufferID;
|
||||
|
||||
@@ -59,9 +59,7 @@ typedef struct ALsource
|
||||
|
||||
struct ALbufferlistitem *queue; // Linked list of buffers in queue
|
||||
ALuint BuffersInQueue; // Number of buffers in queue
|
||||
|
||||
ALuint TotalBufferDataSize; // Total amount of data contained in the buffers queued for this source
|
||||
ALuint BuffersPlayed; // Number of buffers played on this loop
|
||||
ALuint BuffersPlayed; // Number of buffers played on this loop
|
||||
|
||||
ALfilter DirectFilter;
|
||||
|
||||
@@ -69,6 +67,7 @@ typedef struct ALsource
|
||||
struct ALeffectslot *Slot;
|
||||
ALfilter WetFilter;
|
||||
FILTER iirFilter;
|
||||
ALfloat history[2];
|
||||
} Send[MAX_SENDS];
|
||||
|
||||
ALboolean DryGainHFAuto;
|
||||
@@ -77,6 +76,7 @@ typedef struct ALsource
|
||||
ALfloat OuterGainHF;
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[OUTPUTCHANNELS*2];
|
||||
|
||||
ALfloat AirAbsorptionFactor;
|
||||
|
||||
@@ -95,7 +95,7 @@ typedef struct ALsource
|
||||
|
||||
// Current gains, which are ramped while mixed
|
||||
ALfloat DryGains[OUTPUTCHANNELS];
|
||||
ALfloat WetGain;
|
||||
ALfloat WetGains[MAX_SENDS];
|
||||
ALboolean FirstStart;
|
||||
|
||||
struct ALsource *next;
|
||||
|
||||
+126
-4
@@ -3,6 +3,48 @@
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#ifdef HAVE_FLOAT_H
|
||||
#include <float.h>
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 /* pi */
|
||||
#define M_PI_2 1.57079632679489661923 /* pi/2 */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SQRTF
|
||||
#define aluSqrt(x) ((ALfloat)sqrtf((float)(x)))
|
||||
#else
|
||||
#define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACOSF
|
||||
#define aluAcos(x) ((ALfloat)acosf((float)(x)))
|
||||
#else
|
||||
#define aluAcos(x) ((ALfloat)acos((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATANF
|
||||
#define aluAtan(x) ((ALfloat)atanf((float)(x)))
|
||||
#else
|
||||
#define aluAtan(x) ((ALfloat)atan((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FABSF
|
||||
#define aluFabs(x) ((ALfloat)fabsf((float)(x)))
|
||||
#else
|
||||
#define aluFabs(x) ((ALfloat)fabs((double)(x)))
|
||||
#endif
|
||||
|
||||
// fixes for mingw32.
|
||||
#if defined(max) && !defined(__max)
|
||||
#define __max max
|
||||
#endif
|
||||
#if defined(min) && !defined(__min)
|
||||
#define __min min
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -11,21 +53,101 @@ extern "C" {
|
||||
enum {
|
||||
FRONT_LEFT = 0,
|
||||
FRONT_RIGHT,
|
||||
FRONT_CENTER,
|
||||
SIDE_LEFT,
|
||||
SIDE_RIGHT,
|
||||
BACK_LEFT,
|
||||
BACK_RIGHT,
|
||||
CENTER,
|
||||
BACK_CENTER,
|
||||
LFE,
|
||||
|
||||
OUTPUTCHANNELS
|
||||
};
|
||||
|
||||
#define BUFFERSIZE 24000
|
||||
|
||||
extern ALboolean DuplicateStereo;
|
||||
|
||||
__inline ALuint aluBytesFromFormat(ALenum format);
|
||||
__inline ALuint aluChannelsFromFormat(ALenum format);
|
||||
ALvoid aluMixData(ALCcontext *context,ALvoid *buffer,ALsizei size,ALenum format);
|
||||
/* NOTE: The AL_FORMAT_REAR* enums aren't handled here be cause they're
|
||||
* converted to AL_FORMAT_QUAD* when loaded */
|
||||
static __inline ALuint aluBytesFromFormat(ALenum format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case AL_FORMAT_MONO8:
|
||||
case AL_FORMAT_STEREO8:
|
||||
case AL_FORMAT_QUAD8_LOKI:
|
||||
case AL_FORMAT_QUAD8:
|
||||
case AL_FORMAT_51CHN8:
|
||||
case AL_FORMAT_61CHN8:
|
||||
case AL_FORMAT_71CHN8:
|
||||
return 1;
|
||||
|
||||
case AL_FORMAT_MONO16:
|
||||
case AL_FORMAT_STEREO16:
|
||||
case AL_FORMAT_QUAD16_LOKI:
|
||||
case AL_FORMAT_QUAD16:
|
||||
case AL_FORMAT_51CHN16:
|
||||
case AL_FORMAT_61CHN16:
|
||||
case AL_FORMAT_71CHN16:
|
||||
return 2;
|
||||
|
||||
case AL_FORMAT_MONO_FLOAT32:
|
||||
case AL_FORMAT_STEREO_FLOAT32:
|
||||
case AL_FORMAT_QUAD32:
|
||||
case AL_FORMAT_51CHN32:
|
||||
case AL_FORMAT_61CHN32:
|
||||
case AL_FORMAT_71CHN32:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
static __inline ALuint aluChannelsFromFormat(ALenum format)
|
||||
{
|
||||
switch(format)
|
||||
{
|
||||
case AL_FORMAT_MONO8:
|
||||
case AL_FORMAT_MONO16:
|
||||
case AL_FORMAT_MONO_FLOAT32:
|
||||
return 1;
|
||||
|
||||
case AL_FORMAT_STEREO8:
|
||||
case AL_FORMAT_STEREO16:
|
||||
case AL_FORMAT_STEREO_FLOAT32:
|
||||
return 2;
|
||||
|
||||
case AL_FORMAT_QUAD8_LOKI:
|
||||
case AL_FORMAT_QUAD16_LOKI:
|
||||
case AL_FORMAT_QUAD8:
|
||||
case AL_FORMAT_QUAD16:
|
||||
case AL_FORMAT_QUAD32:
|
||||
return 4;
|
||||
|
||||
case AL_FORMAT_51CHN8:
|
||||
case AL_FORMAT_51CHN16:
|
||||
case AL_FORMAT_51CHN32:
|
||||
return 6;
|
||||
|
||||
case AL_FORMAT_61CHN8:
|
||||
case AL_FORMAT_61CHN16:
|
||||
case AL_FORMAT_61CHN32:
|
||||
return 7;
|
||||
|
||||
case AL_FORMAT_71CHN8:
|
||||
case AL_FORMAT_71CHN16:
|
||||
case AL_FORMAT_71CHN32:
|
||||
return 8;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ALvoid aluInitPanning(ALCcontext *Context);
|
||||
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
|
||||
ALvoid aluHandleDisconnect(ALCdevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+52
-96
@@ -29,7 +29,6 @@
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
#include "alReverb.h"
|
||||
|
||||
|
||||
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect);
|
||||
@@ -38,20 +37,16 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot,
|
||||
ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei i;
|
||||
ALsizei i, j;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
/* NOTE: We only support one slot currently */
|
||||
if(n == 1 && Context->AuxiliaryEffectSlotCount == 0)
|
||||
ALCdevice *Device = Context->Device;
|
||||
|
||||
if(Context->AuxiliaryEffectSlotCount+n <= Device->AuxiliaryEffectSlotMax)
|
||||
{
|
||||
// Check that enough memory has been allocted in the 'effectslots' array for n Effect Slots
|
||||
if (!IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
|
||||
@@ -74,6 +69,8 @@ ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
|
||||
(*list)->Gain = 1.0;
|
||||
(*list)->AuxSendAuto = AL_TRUE;
|
||||
for(j = 0;j < BUFFERSIZE;j++)
|
||||
(*list)->WetBuffer[j] = 0.0f;
|
||||
(*list)->refcount = 0;
|
||||
|
||||
effectslots[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
|
||||
@@ -99,13 +96,8 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
ALeffectslot *ALAuxiliaryEffectSlot;
|
||||
ALsizei i;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
@@ -149,7 +141,8 @@ ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
*list = (*list)->next;
|
||||
ALTHUNK_REMOVEENTRY(ALAuxiliaryEffectSlot->effectslot);
|
||||
|
||||
VerbDestroy(ALAuxiliaryEffectSlot->ReverbState);
|
||||
if(ALAuxiliaryEffectSlot->EffectState)
|
||||
ALEffect_Destroy(ALAuxiliaryEffectSlot->EffectState);
|
||||
|
||||
memset(ALAuxiliaryEffectSlot, 0, sizeof(ALeffectslot));
|
||||
free(ALAuxiliaryEffectSlot);
|
||||
@@ -170,13 +163,8 @@ ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
|
||||
ALCcontext *Context;
|
||||
ALeffectslot **list;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return AL_FALSE;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
list = &Context->AuxiliaryEffectSlot;
|
||||
while(*list && (*list)->effectslot != effectslot)
|
||||
@@ -191,13 +179,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -237,13 +220,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALin
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -269,13 +247,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALflo
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -305,13 +278,8 @@ ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfl
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -336,13 +304,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, AL
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -373,13 +336,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, A
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -405,13 +363,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, AL
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -438,13 +391,8 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
if(!Context)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsAuxiliaryEffectSlot(effectslot))
|
||||
{
|
||||
@@ -468,37 +416,45 @@ ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, A
|
||||
|
||||
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot, ALeffect *effect)
|
||||
{
|
||||
if((!effect) || (effect->type != ALEffectSlot->effect.type))
|
||||
{
|
||||
ALeffectState *NewState = NULL;
|
||||
if(effect)
|
||||
{
|
||||
if(effect->type == AL_EFFECT_EAXREVERB)
|
||||
NewState = EAXVerbCreate(Context);
|
||||
else if(effect->type == AL_EFFECT_REVERB)
|
||||
NewState = VerbCreate(Context);
|
||||
else if(effect->type == AL_EFFECT_ECHO)
|
||||
NewState = EchoCreate(Context);
|
||||
/* No new state? An error occured.. */
|
||||
if(!NewState)
|
||||
return;
|
||||
}
|
||||
if(ALEffectSlot->EffectState)
|
||||
ALEffect_Destroy(ALEffectSlot->EffectState);
|
||||
ALEffectSlot->EffectState = NewState;
|
||||
}
|
||||
if(!effect)
|
||||
{
|
||||
memset(&ALEffectSlot->effect, 0, sizeof(ALEffectSlot->effect));
|
||||
VerbDestroy(ALEffectSlot->ReverbState);
|
||||
ALEffectSlot->ReverbState = NULL;
|
||||
return;
|
||||
}
|
||||
if(effect->type == AL_EFFECT_REVERB)
|
||||
{
|
||||
if(!ALEffectSlot->ReverbState)
|
||||
ALEffectSlot->ReverbState = VerbCreate(Context);
|
||||
VerbUpdate(Context, ALEffectSlot, effect);
|
||||
}
|
||||
memcpy(&ALEffectSlot->effect, effect, sizeof(*effect));
|
||||
ALEffect_Update(ALEffectSlot->EffectState, Context, effect);
|
||||
}
|
||||
|
||||
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(Context->AuxiliaryEffectSlotCount > 0)
|
||||
AL_PRINT("alcDestroyContext(): deleting %d AuxiliaryEffectSlot(s)\n", Context->AuxiliaryEffectSlotCount);
|
||||
#endif
|
||||
|
||||
while(Context->AuxiliaryEffectSlot)
|
||||
{
|
||||
ALeffectslot *temp = Context->AuxiliaryEffectSlot;
|
||||
Context->AuxiliaryEffectSlot = Context->AuxiliaryEffectSlot->next;
|
||||
|
||||
// Release effectslot structure
|
||||
VerbDestroy(temp->ReverbState);
|
||||
if(temp->EffectState)
|
||||
ALEffect_Destroy(temp->EffectState);
|
||||
ALTHUNK_REMOVEENTRY(temp->effectslot);
|
||||
|
||||
memset(temp, 0, sizeof(ALeffectslot));
|
||||
|
||||
+82
-53
@@ -18,8 +18,6 @@
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE // get rid of sprintf security warnings on VS2005
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -30,6 +28,7 @@
|
||||
#include "AL/alc.h"
|
||||
#include "alError.h"
|
||||
#include "alBuffer.h"
|
||||
#include "alDatabuffer.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
|
||||
@@ -51,9 +50,6 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
|
||||
* Global Variables
|
||||
*/
|
||||
|
||||
static ALbuffer *g_pBuffers = NULL; // Linked List of Buffers
|
||||
static ALuint g_uiBufferCount = 0; // Buffer Count
|
||||
|
||||
static const long g_IMAStep_size[89]={ // IMA ADPCM Stepsize table
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
|
||||
34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143,
|
||||
@@ -83,16 +79,18 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
|
||||
ALCcontext *Context;
|
||||
ALsizei i=0;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
// Check that we are actually generation some Buffers
|
||||
if (n > 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
// Check the pointer is valid (and points to enough memory to store Buffer Names)
|
||||
if (!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
|
||||
{
|
||||
ALbuffer **list = &g_pBuffers;
|
||||
ALbuffer **list = &device->Buffers;
|
||||
while(*list)
|
||||
list = &(*list)->next;
|
||||
|
||||
@@ -109,7 +107,7 @@ ALAPI ALvoid ALAPIENTRY alGenBuffers(ALsizei n,ALuint *puiBuffers)
|
||||
|
||||
puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
|
||||
(*list)->state = UNUSED;
|
||||
g_uiBufferCount++;
|
||||
device->BufferCount++;
|
||||
i++;
|
||||
|
||||
list = &(*list)->next;
|
||||
@@ -139,12 +137,14 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
|
||||
ALsizei i;
|
||||
ALboolean bFailed = AL_FALSE;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
// Check we are actually Deleting some Buffers
|
||||
if (n >= 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
// Check that all the buffers are valid and can actually be deleted
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
@@ -178,7 +178,7 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
|
||||
{
|
||||
if (puiBuffers[i] && alIsBuffer(puiBuffers[i]))
|
||||
{
|
||||
ALbuffer **list = &g_pBuffers;
|
||||
ALbuffer **list = &device->Buffers;
|
||||
|
||||
ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
|
||||
while(*list && *list != ALBuf)
|
||||
@@ -193,7 +193,7 @@ ALAPI ALvoid ALAPIENTRY alDeleteBuffers(ALsizei n, const ALuint *puiBuffers)
|
||||
// Release buffer structure
|
||||
ALTHUNK_REMOVEENTRY(puiBuffers[i]);
|
||||
memset(ALBuf, 0, sizeof(ALbuffer));
|
||||
g_uiBufferCount--;
|
||||
device->BufferCount--;
|
||||
free(ALBuf);
|
||||
}
|
||||
}
|
||||
@@ -220,15 +220,17 @@ ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
|
||||
ALbuffer *ALBuf;
|
||||
ALbuffer *TgtALBuf;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
if (uiBuffer)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
TgtALBuf = (ALbuffer *)ALTHUNK_LOOKUPENTRY(uiBuffer);
|
||||
|
||||
// Check through list of generated buffers for uiBuffer
|
||||
ALBuf = g_pBuffers;
|
||||
ALBuf = device->Buffers;
|
||||
while (ALBuf)
|
||||
{
|
||||
if (ALBuf == TgtALBuf)
|
||||
@@ -263,12 +265,28 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
ALbuffer *ALBuf;
|
||||
ALvoid *temp;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
|
||||
|
||||
if(Context->SampleSource)
|
||||
{
|
||||
ALuint offset;
|
||||
|
||||
if(Context->SampleSource->state == MAPPED)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
ProcessContext(Context);
|
||||
return;
|
||||
}
|
||||
|
||||
offset = (ALuint)data;
|
||||
data = Context->SampleSource->data + offset;
|
||||
}
|
||||
|
||||
if ((ALBuf->refcount==0)&&(data))
|
||||
{
|
||||
switch(format)
|
||||
@@ -415,12 +433,28 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
ALCcontext *Context;
|
||||
ALbuffer *ALBuf;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(alIsBuffer(buffer) && buffer != 0)
|
||||
{
|
||||
ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
|
||||
|
||||
if(Context->SampleSource)
|
||||
{
|
||||
ALuint offset;
|
||||
|
||||
if(Context->SampleSource->state == MAPPED)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
ProcessContext(Context);
|
||||
return;
|
||||
}
|
||||
|
||||
offset = (ALuint)data;
|
||||
data = Context->SampleSource->data + offset;
|
||||
}
|
||||
|
||||
if(ALBuf->data == NULL)
|
||||
{
|
||||
// buffer does not have any data
|
||||
@@ -516,8 +550,8 @@ ALAPI void ALAPIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue)
|
||||
|
||||
(void)flValue;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -545,8 +579,8 @@ ALAPI void ALAPIENTRY alBuffer3f(ALuint buffer, ALenum eParam, ALfloat flValue1,
|
||||
(void)flValue2;
|
||||
(void)flValue3;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -572,8 +606,8 @@ ALAPI void ALAPIENTRY alBufferfv(ALuint buffer, ALenum eParam, const ALfloat* fl
|
||||
|
||||
(void)flValues;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -599,8 +633,8 @@ ALAPI void ALAPIENTRY alBufferi(ALuint buffer, ALenum eParam, ALint lValue)
|
||||
|
||||
(void)lValue;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -628,8 +662,8 @@ ALAPI void ALAPIENTRY alBuffer3i( ALuint buffer, ALenum eParam, ALint lValue1, A
|
||||
(void)lValue2;
|
||||
(void)lValue3;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -655,8 +689,8 @@ ALAPI void ALAPIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* plVa
|
||||
|
||||
(void)plValues;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (alIsBuffer(buffer) && (buffer != 0))
|
||||
{
|
||||
@@ -680,8 +714,8 @@ ALAPI ALvoid ALAPIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pflV
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (pflValue)
|
||||
{
|
||||
@@ -712,8 +746,8 @@ ALAPI void ALAPIENTRY alGetBuffer3f(ALuint buffer, ALenum eParam, ALfloat* pflVa
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if ((pflValue1) && (pflValue2) && (pflValue3))
|
||||
{
|
||||
@@ -744,8 +778,8 @@ ALAPI void ALAPIENTRY alGetBufferfv(ALuint buffer, ALenum eParam, ALfloat* pflVa
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (pflValues)
|
||||
{
|
||||
@@ -777,8 +811,8 @@ ALAPI ALvoid ALAPIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plValu
|
||||
ALCcontext *pContext;
|
||||
ALbuffer *pBuffer;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (plValue)
|
||||
{
|
||||
@@ -827,8 +861,8 @@ ALAPI void ALAPIENTRY alGetBuffer3i(ALuint buffer, ALenum eParam, ALint* plValue
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if ((plValue1) && (plValue2) && (plValue3))
|
||||
{
|
||||
@@ -859,8 +893,8 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (plValues)
|
||||
{
|
||||
@@ -1071,17 +1105,12 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
|
||||
*
|
||||
* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
|
||||
*/
|
||||
ALvoid ReleaseALBuffers(ALvoid)
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device)
|
||||
{
|
||||
ALbuffer *ALBuffer;
|
||||
ALbuffer *ALBufferTemp;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(g_uiBufferCount > 0)
|
||||
AL_PRINT("exit(): deleting %d Buffer(s)\n", g_uiBufferCount);
|
||||
#endif
|
||||
|
||||
ALBuffer = g_pBuffers;
|
||||
ALBuffer = device->Buffers;
|
||||
while(ALBuffer)
|
||||
{
|
||||
// Release sample data
|
||||
@@ -1093,6 +1122,6 @@ ALvoid ReleaseALBuffers(ALvoid)
|
||||
memset(ALBufferTemp, 0, sizeof(ALbuffer));
|
||||
free(ALBufferTemp);
|
||||
}
|
||||
g_pBuffers = NULL;
|
||||
g_uiBufferCount = 0;
|
||||
device->Buffers = NULL;
|
||||
device->BufferCount = 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,639 @@
|
||||
/**
|
||||
* OpenAL cross platform audio library
|
||||
* Copyright (C) 1999-2007 by authors.
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
* Or go to http://www.gnu.org/copyleft/lgpl.html
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "alError.h"
|
||||
#include "alDatabuffer.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
|
||||
/*
|
||||
* alGenDatabuffersEXT(ALsizei n, ALuint *puiBuffers)
|
||||
*
|
||||
* Generates n AL Databuffers, and stores the Databuffers Names in the array pointed to by puiBuffers
|
||||
*/
|
||||
ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei i=0;
|
||||
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
/* Check that we are actually generation some Databuffers */
|
||||
if(n > 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
/* Check the pointer is valid (and points to enough memory to store
|
||||
* Databuffer Names) */
|
||||
if(!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
|
||||
{
|
||||
ALdatabuffer **list = &device->Databuffers;
|
||||
while(*list)
|
||||
list = &(*list)->next;
|
||||
|
||||
/* Create all the new Databuffers */
|
||||
while(i < n)
|
||||
{
|
||||
*list = calloc(1, sizeof(ALdatabuffer));
|
||||
if(!(*list))
|
||||
{
|
||||
alDeleteDatabuffersEXT(i, puiBuffers);
|
||||
alSetError(AL_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
|
||||
puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
|
||||
(*list)->databuffer = puiBuffers[i];
|
||||
(*list)->state = UNMAPPED;
|
||||
device->DatabufferCount++;
|
||||
i++;
|
||||
|
||||
list = &(*list)->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
/*
|
||||
* alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
|
||||
*
|
||||
* Deletes the n AL Databuffers pointed to by puiBuffers
|
||||
*/
|
||||
ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALdatabuffer *ALBuf;
|
||||
ALsizei i;
|
||||
ALboolean bFailed = AL_FALSE;
|
||||
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
/* Check we are actually Deleting some Databuffers */
|
||||
if(n >= 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
/* Check that all the databuffers are valid and can actually be
|
||||
* deleted */
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
/* Check for valid Buffer ID (can be NULL buffer) */
|
||||
if(alIsDatabufferEXT(puiBuffers[i]))
|
||||
{
|
||||
/* If not the NULL buffer, check that it's unmapped */
|
||||
ALBuf = ((ALdatabuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
|
||||
if(ALBuf)
|
||||
{
|
||||
if(ALBuf->state != UNMAPPED)
|
||||
{
|
||||
/* Databuffer still in use, cannot be deleted */
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
bFailed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid Databuffer */
|
||||
alSetError(AL_INVALID_NAME);
|
||||
bFailed = AL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If all the Databuffers were valid (and unmapped), then we can
|
||||
* delete them */
|
||||
if(!bFailed)
|
||||
{
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if(puiBuffers[i] && alIsDatabufferEXT(puiBuffers[i]))
|
||||
{
|
||||
ALdatabuffer **list = &device->Databuffers;
|
||||
|
||||
ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(puiBuffers[i]);
|
||||
while(*list && *list != ALBuf)
|
||||
list = &(*list)->next;
|
||||
|
||||
if(*list)
|
||||
*list = (*list)->next;
|
||||
|
||||
if(ALBuf == Context->SampleSource)
|
||||
Context->SampleSource = NULL;
|
||||
if(ALBuf == Context->SampleSink)
|
||||
Context->SampleSink = NULL;
|
||||
|
||||
// Release the memory used to store audio data
|
||||
free(ALBuf->data);
|
||||
|
||||
// Release buffer structure
|
||||
ALTHUNK_REMOVEENTRY(puiBuffers[i]);
|
||||
memset(ALBuf, 0, sizeof(ALdatabuffer));
|
||||
device->DatabufferCount--;
|
||||
free(ALBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* alIsDatabufferEXT(ALuint uiBuffer)
|
||||
*
|
||||
* Checks if ulBuffer is a valid Databuffer Name
|
||||
*/
|
||||
ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALdatabuffer *ALBuf;
|
||||
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
/* Check through list of generated databuffers for uiBuffer */
|
||||
ALBuf = Context->Device->Databuffers;
|
||||
while(ALBuf && ALBuf->databuffer != uiBuffer)
|
||||
ALBuf = ALBuf->next;
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return ((ALBuf || !uiBuffer) ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
|
||||
*
|
||||
* Fill databuffer with data
|
||||
*/
|
||||
ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALdatabuffer *ALBuf;
|
||||
ALvoid *temp;
|
||||
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
|
||||
if(ALBuf->state == UNMAPPED)
|
||||
{
|
||||
if(usage == AL_STREAM_WRITE_EXT || usage == AL_STREAM_READ_EXT ||
|
||||
usage == AL_STREAM_COPY_EXT || usage == AL_STATIC_WRITE_EXT ||
|
||||
usage == AL_STATIC_READ_EXT || usage == AL_STATIC_COPY_EXT ||
|
||||
usage == AL_DYNAMIC_WRITE_EXT || usage == AL_DYNAMIC_READ_EXT ||
|
||||
usage == AL_DYNAMIC_COPY_EXT)
|
||||
{
|
||||
/* (Re)allocate data */
|
||||
temp = realloc(ALBuf->data, size);
|
||||
if(temp)
|
||||
{
|
||||
ALBuf->data = temp;
|
||||
ALBuf->size = size;
|
||||
ALBuf->usage = usage;
|
||||
if(data)
|
||||
memcpy(ALBuf->data, data, size);
|
||||
}
|
||||
else
|
||||
alSetError(AL_OUT_OF_MEMORY);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, const ALvoid *data)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
|
||||
|
||||
if(length >= 0 && start+length <= pBuffer->size)
|
||||
{
|
||||
if(pBuffer->state == UNMAPPED)
|
||||
memcpy(pBuffer->data+start, data, length);
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALvoid *data)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
|
||||
|
||||
if(length >= 0 && start+length <= pBuffer->size)
|
||||
{
|
||||
if(pBuffer->state == UNMAPPED)
|
||||
memcpy(data, pBuffer->data+start, length);
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
(void)flValue;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
(void)flValues;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
(void)lValue;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
(void)plValues;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(pflValue)
|
||||
{
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(pflValues)
|
||||
{
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(plValue)
|
||||
{
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_SIZE:
|
||||
*plValue = pBuffer->size;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(plValues)
|
||||
{
|
||||
if(alIsDatabufferEXT(buffer) && buffer != 0)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_SIZE:
|
||||
alGetBufferi(buffer, eParam, plValues);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(uiBuffer))
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)(uiBuffer ? ALTHUNK_LOOKUPENTRY(uiBuffer) : NULL);
|
||||
if(target == AL_SAMPLE_SOURCE_EXT)
|
||||
pContext->SampleSource = pBuffer;
|
||||
else if(target == AL_SAMPLE_SINK_EXT)
|
||||
pContext->SampleSink = pBuffer;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
ALvoid *ret = NULL;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return NULL;
|
||||
|
||||
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
|
||||
|
||||
if(length >= 0 && start+length <= pBuffer->size)
|
||||
{
|
||||
if(access == AL_READ_ONLY_EXT || access == AL_WRITE_ONLY_EXT ||
|
||||
access == AL_READ_WRITE_EXT)
|
||||
{
|
||||
if(pBuffer->state == UNMAPPED)
|
||||
{
|
||||
ret = pBuffer->data + start;
|
||||
pBuffer->state = MAPPED;
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
ALdatabuffer *pBuffer;
|
||||
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
|
||||
{
|
||||
pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
|
||||
|
||||
if(pBuffer->state == MAPPED)
|
||||
pBuffer->state = UNMAPPED;
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_NAME);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ReleaseALDatabuffers()
|
||||
*
|
||||
* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
|
||||
*/
|
||||
ALvoid ReleaseALDatabuffers(ALCdevice *device)
|
||||
{
|
||||
ALdatabuffer *ALBuffer;
|
||||
ALdatabuffer *ALBufferTemp;
|
||||
|
||||
ALBuffer = device->Databuffers;
|
||||
while(ALBuffer)
|
||||
{
|
||||
// Release sample data
|
||||
free(ALBuffer->data);
|
||||
|
||||
// Release Buffer structure
|
||||
ALBufferTemp = ALBuffer;
|
||||
ALBuffer = ALBuffer->next;
|
||||
memset(ALBufferTemp, 0, sizeof(ALdatabuffer));
|
||||
free(ALBufferTemp);
|
||||
}
|
||||
device->Databuffers = NULL;
|
||||
device->DatabufferCount = 0;
|
||||
}
|
||||
+669
-77
File diff suppressed because it is too large
Load Diff
+16
-21
@@ -26,34 +26,29 @@
|
||||
|
||||
ALAPI ALenum ALAPIENTRY alGetError(ALvoid)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_INVALID_OPERATION;
|
||||
|
||||
if (Context)
|
||||
{
|
||||
errorCode = Context->LastError;
|
||||
Context->LastError = AL_NO_ERROR;
|
||||
}
|
||||
else
|
||||
errorCode = AL_INVALID_OPERATION;
|
||||
errorCode = Context->LastError;
|
||||
Context->LastError = AL_NO_ERROR;
|
||||
|
||||
ProcessContext(Context);
|
||||
ProcessContext(Context);
|
||||
|
||||
return errorCode;
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ALvoid alSetError(ALenum errorCode)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
|
||||
if (Context && Context->LastError == AL_NO_ERROR)
|
||||
Context->LastError = errorCode;
|
||||
|
||||
ProcessContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(Context)
|
||||
{
|
||||
if(Context->LastError == AL_NO_ERROR)
|
||||
Context->LastError = errorCode;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-8
@@ -29,6 +29,7 @@
|
||||
#include "alFilter.h"
|
||||
#include "alEffect.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alDatabuffer.h"
|
||||
#include "alSource.h"
|
||||
#include "alBuffer.h"
|
||||
#include "AL/al.h"
|
||||
@@ -147,6 +148,24 @@ static ALfunction function[]= {
|
||||
|
||||
{ "alBufferSubDataEXT", (ALvoid *) alBufferSubDataEXT },
|
||||
|
||||
{ "alGenDatabuffersEXT", (ALvoid *) alGenDatabuffersEXT },
|
||||
{ "alDeleteDatabuffersEXT", (ALvoid *) alDeleteDatabuffersEXT },
|
||||
{ "alIsDatabufferEXT", (ALvoid *) alIsDatabufferEXT },
|
||||
{ "alDatabufferDataEXT", (ALvoid *) alDatabufferDataEXT },
|
||||
{ "alDatabufferSubDataEXT", (ALvoid *) alDatabufferSubDataEXT },
|
||||
{ "alGetDatabufferSubDataEXT", (ALvoid *) alGetDatabufferSubDataEXT },
|
||||
{ "alDatabufferfEXT", (ALvoid *) alDatabufferfEXT },
|
||||
{ "alDatabufferfvEXT", (ALvoid *) alDatabufferfvEXT },
|
||||
{ "alDatabufferiEXT", (ALvoid *) alDatabufferiEXT },
|
||||
{ "alDatabufferivEXT", (ALvoid *) alDatabufferivEXT },
|
||||
{ "alGetDatabufferfEXT", (ALvoid *) alGetDatabufferfEXT },
|
||||
{ "alGetDatabufferfvEXT", (ALvoid *) alGetDatabufferfvEXT },
|
||||
{ "alGetDatabufferiEXT", (ALvoid *) alGetDatabufferiEXT },
|
||||
{ "alGetDatabufferivEXT", (ALvoid *) alGetDatabufferivEXT },
|
||||
{ "alSelectDatabufferEXT", (ALvoid *) alSelectDatabufferEXT },
|
||||
{ "alMapDatabufferEXT", (ALvoid *) alMapDatabufferEXT },
|
||||
{ "alUnmapDatabufferEXT", (ALvoid *) alUnmapDatabufferEXT },
|
||||
|
||||
{ NULL, (ALvoid *) NULL } };
|
||||
|
||||
static ALenums enumeration[]={
|
||||
@@ -333,14 +352,8 @@ ALAPI ALboolean ALAPIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if(!pContext)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return AL_FALSE;
|
||||
|
||||
len = strlen(extName);
|
||||
ptr = pContext->ExtensionList;
|
||||
|
||||
+42
-43
@@ -29,8 +29,6 @@
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
|
||||
static ALfilter *g_FilterList;
|
||||
static ALuint g_FilterCount;
|
||||
|
||||
static void InitFilterParams(ALfilter *filter, ALenum type);
|
||||
|
||||
@@ -40,15 +38,17 @@ ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
|
||||
ALCcontext *Context;
|
||||
ALsizei i;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
// Check that enough memory has been allocted in the 'filters' array for n Filters
|
||||
if (!IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
|
||||
{
|
||||
ALfilter **list = &g_FilterList;
|
||||
ALfilter **list = &device->FilterList;
|
||||
while(*list)
|
||||
list = &(*list)->next;
|
||||
|
||||
@@ -68,7 +68,7 @@ ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
|
||||
(*list)->filter = filters[i];
|
||||
|
||||
InitFilterParams(*list, AL_FILTER_NULL);
|
||||
g_FilterCount++;
|
||||
device->FilterCount++;
|
||||
i++;
|
||||
|
||||
list = &(*list)->next;
|
||||
@@ -85,11 +85,13 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
|
||||
ALfilter *ALFilter;
|
||||
ALsizei i;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (n >= 0)
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
|
||||
// Check that all filters are valid
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
@@ -113,7 +115,7 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
|
||||
ALFilter = ((ALfilter*)ALTHUNK_LOOKUPENTRY(filters[i]));
|
||||
|
||||
// Remove Source from list of Sources
|
||||
list = &g_FilterList;
|
||||
list = &device->FilterList;
|
||||
while(*list && *list != ALFilter)
|
||||
list = &(*list)->next;
|
||||
|
||||
@@ -124,7 +126,7 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
|
||||
memset(ALFilter, 0, sizeof(ALfilter));
|
||||
free(ALFilter);
|
||||
|
||||
g_FilterCount--;
|
||||
device->FilterCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,26 +140,26 @@ ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
|
||||
ALboolean AL_APIENTRY alIsFilter(ALuint filter)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALfilter **list;
|
||||
ALfilter *list;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
list = &g_FilterList;
|
||||
while(*list && (*list)->filter != filter)
|
||||
list = &(*list)->next;
|
||||
list = Context->Device->FilterList;
|
||||
while(list && list->filter != filter)
|
||||
list = list->next;
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return ((*list || !filter) ? AL_TRUE : AL_FALSE);
|
||||
return ((list || !filter) ? AL_TRUE : AL_FALSE);
|
||||
}
|
||||
|
||||
ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -188,8 +190,8 @@ ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -214,8 +216,8 @@ ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -261,8 +263,8 @@ ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -283,8 +285,8 @@ ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -311,8 +313,8 @@ ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -337,8 +339,8 @@ ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -378,8 +380,8 @@ ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = alcGetCurrentContext();
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (filter && alIsFilter(filter))
|
||||
{
|
||||
@@ -397,23 +399,20 @@ ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues
|
||||
}
|
||||
|
||||
|
||||
ALvoid ReleaseALFilters(ALvoid)
|
||||
ALvoid ReleaseALFilters(ALCdevice *device)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
if(g_FilterCount > 0)
|
||||
AL_PRINT("exit(): deleting %d Filter(s)\n", g_FilterCount);
|
||||
#endif
|
||||
|
||||
while(g_FilterList)
|
||||
ALfilter *list = device->FilterList;
|
||||
while(list)
|
||||
{
|
||||
ALfilter *temp = g_FilterList;
|
||||
g_FilterList = g_FilterList->next;
|
||||
ALfilter *temp = list;
|
||||
list = list->next;
|
||||
|
||||
// Release filter structure
|
||||
memset(temp, 0, sizeof(ALfilter));
|
||||
free(temp);
|
||||
}
|
||||
g_FilterCount = 0;
|
||||
device->FilterList = NULL;
|
||||
device->FilterCount = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+80
-164
@@ -29,22 +29,20 @@ ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
switch (eParam)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
if (flValue >= 0.0f)
|
||||
if(flValue >= 0.0f)
|
||||
pContext->Listener.Gain = flValue;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
if (flValue > 0.0f)
|
||||
if(flValue > 0.0f)
|
||||
pContext->Listener.MetersPerUnit = flValue;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
@@ -53,14 +51,9 @@ ALAPI ALvoid ALAPIENTRY alListenerf(ALenum eParam, ALfloat flValue)
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,13 +61,11 @@ ALAPI ALvoid ALAPIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat fl
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
pContext->Listener.Position[0] = flValue1;
|
||||
pContext->Listener.Position[1] = flValue2;
|
||||
@@ -90,14 +81,9 @@ ALAPI ALvoid ALAPIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat fl
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,24 +91,22 @@ ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (pflValues)
|
||||
if(pflValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
if (pflValues[0] >= 0.0f)
|
||||
if(pflValues[0] >= 0.0f)
|
||||
pContext->Listener.Gain = pflValues[0];
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
if (pflValues[0] > 0.0f)
|
||||
if(pflValues[0] > 0.0f)
|
||||
pContext->Listener.MetersPerUnit = pflValues[0];
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
@@ -153,17 +137,12 @@ ALAPI ALvoid ALAPIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -173,24 +152,17 @@ ALAPI ALvoid ALAPIENTRY alListeneri(ALenum eParam, ALint lValue)
|
||||
|
||||
(void)lValue;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
switch (eParam)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,13 +170,11 @@ ALAPI void ALAPIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2,
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
|
||||
@@ -213,14 +183,9 @@ ALAPI void ALAPIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2,
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -229,15 +194,13 @@ ALAPI void ALAPIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
|
||||
ALCcontext *pContext;
|
||||
ALfloat flValues[6];
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (plValues)
|
||||
if(plValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
flValues[0] = (ALfloat)plValues[0];
|
||||
@@ -259,17 +222,12 @@ ALAPI void ALAPIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -277,15 +235,13 @@ ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (pflValue)
|
||||
if(pflValue)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
*pflValue = pContext->Listener.Gain;
|
||||
break;
|
||||
@@ -297,17 +253,12 @@ ALAPI ALvoid ALAPIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -315,15 +266,13 @@ ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALflo
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if ((pflValue1) && (pflValue2) && (pflValue3))
|
||||
if(pflValue1 && pflValue2 && pflValue3)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
*pflValue1 = pContext->Listener.Position[0];
|
||||
*pflValue2 = pContext->Listener.Position[1];
|
||||
@@ -339,17 +288,12 @@ ALAPI ALvoid ALAPIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALflo
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -357,15 +301,13 @@ ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (pflValues)
|
||||
if(pflValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
pflValues[0] = pContext->Listener.Gain;
|
||||
break;
|
||||
@@ -399,17 +341,12 @@ ALAPI ALvoid ALAPIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -417,29 +354,22 @@ ALAPI ALvoid ALAPIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (plValue)
|
||||
if(plValue)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -447,15 +377,13 @@ ALAPI void ALAPIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plV
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if ((plValue1) && (plValue2) && (plValue3))
|
||||
if(plValue1 && plValue2 && plValue3)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
*plValue1 = (ALint)pContext->Listener.Position[0];
|
||||
*plValue2 = (ALint)pContext->Listener.Position[1];
|
||||
@@ -471,17 +399,12 @@ ALAPI void ALAPIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plV
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
|
||||
@@ -489,15 +412,13 @@ ALAPI void ALAPIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (plValues)
|
||||
if(plValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
switch (eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
plValues[0] = (ALint)pContext->Listener.Position[0];
|
||||
plValues[1] = (ALint)pContext->Listener.Position[1];
|
||||
@@ -523,15 +444,10 @@ ALAPI void ALAPIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
else
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
+611
-793
File diff suppressed because it is too large
Load Diff
+273
-380
@@ -23,8 +23,11 @@
|
||||
#include <stdlib.h>
|
||||
#include "alMain.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "alError.h"
|
||||
#include "alSource.h"
|
||||
#include "alState.h"
|
||||
#include "alDatabuffer.h"
|
||||
|
||||
static const ALchar alVendor[] = "OpenAL Community";
|
||||
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
|
||||
@@ -42,50 +45,34 @@ ALAPI ALvoid ALAPIENTRY alEnable(ALenum capability)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
switch (capability)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
switch(capability)
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alDisable(ALenum capability)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
switch (capability)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
switch(capability)
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALboolean ALAPIENTRY alIsEnabled(ALenum capability)
|
||||
@@ -93,26 +80,18 @@ ALAPI ALboolean ALAPIENTRY alIsEnabled(ALenum capability)
|
||||
ALCcontext *Context;
|
||||
ALboolean value=AL_FALSE;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
switch (capability)
|
||||
{
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
switch(capability)
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -121,46 +100,38 @@ ALAPI ALboolean ALAPIENTRY alGetBoolean(ALenum pname)
|
||||
ALCcontext *Context;
|
||||
ALboolean value=AL_FALSE;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
case AL_DOPPLER_FACTOR:
|
||||
if(Context->DopplerFactor != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
if (Context->DopplerFactor != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
if(Context->DopplerVelocity != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
if (Context->DopplerVelocity != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
if (Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
if(Context->flSpeedOfSound != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
if (Context->flSpeedOfSound != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -169,42 +140,34 @@ ALAPI ALdouble ALAPIENTRY alGetDouble(ALenum pname)
|
||||
ALCcontext *Context;
|
||||
ALdouble value = 0.0;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return 0.0;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (double)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (double)Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (double)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (double)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (double)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (double)Context->DistanceModel;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (double)Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (double)Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -213,42 +176,34 @@ ALAPI ALfloat ALAPIENTRY alGetFloat(ALenum pname)
|
||||
ALCcontext *Context;
|
||||
ALfloat value = 0.0f;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return 0.0f;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (float)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (float)Context->DistanceModel;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -257,42 +212,48 @@ ALAPI ALint ALAPIENTRY alGetInteger(ALenum pname)
|
||||
ALCcontext *Context;
|
||||
ALint value = 0;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return 0;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (ALint)Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (ALint)Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SAMPLE_SOURCE_EXT:
|
||||
if(Context->SampleSource)
|
||||
value = (ALint)Context->SampleSource->databuffer;
|
||||
else
|
||||
value = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
case AL_SAMPLE_SINK_EXT:
|
||||
if(Context->SampleSink)
|
||||
value = (ALint)Context->SampleSink->databuffer;
|
||||
else
|
||||
value = 0;
|
||||
break;
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -300,204 +261,178 @@ ALAPI ALvoid ALAPIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
|
||||
if (data)
|
||||
switch(pname)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (ALboolean)((Context->DopplerFactor != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (ALboolean)((Context->DopplerFactor != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (ALboolean)((Context->DopplerVelocity != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (ALboolean)((Context->DopplerVelocity != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (ALboolean)((Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (ALboolean)((Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (ALboolean)((Context->flSpeedOfSound != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (ALboolean)((Context->flSpeedOfSound != 0.0f) ? AL_TRUE : AL_FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetDoublev(ALenum pname,ALdouble *data)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
|
||||
if (data)
|
||||
switch(pname)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (double)Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (double)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (double)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (double)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (double)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (double)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (double)Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (double)Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetFloatv(ALenum pname,ALfloat *data)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
|
||||
if (data)
|
||||
switch(pname)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (float)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (float)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alGetIntegerv(ALenum pname,ALint *data)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
|
||||
if (data)
|
||||
switch(pname)
|
||||
{
|
||||
switch (pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
case AL_DOPPLER_FACTOR:
|
||||
*data = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
*data = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
*data = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (ALint)Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
*data = (ALint)Context->flSpeedOfSound;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
case AL_SAMPLE_SOURCE_EXT:
|
||||
if(Context->SampleSource)
|
||||
*data = (ALint)Context->SampleSource->databuffer;
|
||||
else
|
||||
*data = 0;
|
||||
break;
|
||||
|
||||
case AL_SAMPLE_SINK_EXT:
|
||||
if(Context->SampleSink)
|
||||
*data = (ALint)Context->SampleSink->databuffer;
|
||||
else
|
||||
*data = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
// data is a NULL pointer
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI const ALchar* ALAPIENTRY alGetString(ALenum pname)
|
||||
@@ -505,14 +440,8 @@ ALAPI const ALchar* ALAPIENTRY alGetString(ALenum pname)
|
||||
const ALchar *value;
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if(!pContext)
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return NULL;
|
||||
|
||||
switch(pname)
|
||||
{
|
||||
@@ -571,109 +500,73 @@ ALAPI ALvoid ALAPIENTRY alDopplerFactor(ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (value>=0.0f)
|
||||
Context->DopplerFactor = value;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
if(value >= 0.0f)
|
||||
Context->DopplerFactor = value;
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alDopplerVelocity(ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
if (value>0.0f)
|
||||
Context->DopplerVelocity=value;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
if(value > 0.0f)
|
||||
Context->DopplerVelocity=value;
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alSpeedOfSound(ALfloat flSpeedOfSound)
|
||||
{
|
||||
ALCcontext *pContext;
|
||||
|
||||
pContext = alcGetCurrentContext();
|
||||
if (pContext)
|
||||
{
|
||||
SuspendContext(pContext);
|
||||
pContext = GetContextSuspended();
|
||||
if(!pContext) return;
|
||||
|
||||
if (flSpeedOfSound > 0.0f)
|
||||
pContext->flSpeedOfSound = flSpeedOfSound;
|
||||
else
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
if(flSpeedOfSound > 0.0f)
|
||||
pContext->flSpeedOfSound = flSpeedOfSound;
|
||||
else
|
||||
{
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
}
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
|
||||
return;
|
||||
ProcessContext(pContext);
|
||||
}
|
||||
|
||||
ALAPI ALvoid ALAPIENTRY alDistanceModel(ALenum value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsource *Source;
|
||||
|
||||
Context=alcGetCurrentContext();
|
||||
if (Context)
|
||||
Context = GetContextSuspended();
|
||||
if(!Context) return;
|
||||
|
||||
switch(value)
|
||||
{
|
||||
SuspendContext(Context);
|
||||
case AL_NONE:
|
||||
case AL_INVERSE_DISTANCE:
|
||||
case AL_INVERSE_DISTANCE_CLAMPED:
|
||||
case AL_LINEAR_DISTANCE:
|
||||
case AL_LINEAR_DISTANCE_CLAMPED:
|
||||
case AL_EXPONENT_DISTANCE:
|
||||
case AL_EXPONENT_DISTANCE_CLAMPED:
|
||||
Context->DistanceModel = value;
|
||||
for(Source = Context->Source;Source != NULL;Source = Source->next)
|
||||
Source->DistanceModel = value;
|
||||
break;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case AL_NONE:
|
||||
case AL_INVERSE_DISTANCE:
|
||||
case AL_INVERSE_DISTANCE_CLAMPED:
|
||||
case AL_LINEAR_DISTANCE:
|
||||
case AL_LINEAR_DISTANCE_CLAMPED:
|
||||
case AL_EXPONENT_DISTANCE:
|
||||
case AL_EXPONENT_DISTANCE_CLAMPED:
|
||||
Context->DistanceModel = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessContext(Context);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid Context
|
||||
alSetError(AL_INVALID_OPERATION);
|
||||
default:
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
ProcessContext(Context);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Cross-compiling requires CMake 2.6 or newer. To cross-compile, first modify
|
||||
# this file to set the proper settings and paths. Then use it from build/ like:
|
||||
# cmake .. -DCMAKE_TOOLCHAIN_FILE=../XCompile.txt \
|
||||
# -DCMAKE_INSTALL_PREFIX=/usr/mingw32/mingw
|
||||
# If you already have a toolchain file setup, you may use that instead of this
|
||||
# file.
|
||||
|
||||
# the name of the target operating system
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# which compilers to use for C and C++
|
||||
SET(CMAKE_C_COMPILER mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER mingw32-g++)
|
||||
|
||||
# here is the target environment located
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/mingw32/mingw)
|
||||
|
||||
# adjust the default behaviour of the FIND_XXX() commands:
|
||||
# search headers and libraries in the target environment, search
|
||||
# programs in the host environment
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
+182
-76
@@ -10,98 +10,204 @@
|
||||
|
||||
# Option and block names are case-insenstive. The supplied values are only
|
||||
# hints and may not be honored (though generally it'll try to get as close as
|
||||
# possible). These are the current available settings:
|
||||
# possible). Note: options that are left unset may default to app- or system-
|
||||
# specified values. These are the current available settings:
|
||||
|
||||
format = AL_FORMAT_STEREO16 # Sets the output format. Can be one of:
|
||||
# AL_FORMAT_MONO8 (8-bit mono)
|
||||
# AL_FORMAT_STEREO8 (8-bit stereo)
|
||||
# AL_FORMAT_QUAD8 (8-bit 4-channel)
|
||||
# AL_FORMAT_51CHN8 (8-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN8 (8-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN8 (8-bit 7.1 output)
|
||||
# AL_FORMAT_MONO16 (16-bit mono)
|
||||
# AL_FORMAT_STEREO16 (16-bit stereo)
|
||||
# AL_FORMAT_QUAD16 (16-bit 4-channel)
|
||||
# AL_FORMAT_51CHN16 (16-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN16 (16-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN16 (16-bit 7.1 output)
|
||||
# Default is AL_FORMAT_STEREO16
|
||||
## format:
|
||||
# Sets the output format. Can be one of:
|
||||
# AL_FORMAT_MONO8 (8-bit mono)
|
||||
# AL_FORMAT_STEREO8 (8-bit stereo)
|
||||
# AL_FORMAT_QUAD8 (8-bit 4-channel)
|
||||
# AL_FORMAT_51CHN8 (8-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN8 (8-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN8 (8-bit 7.1 output)
|
||||
# AL_FORMAT_MONO16 (16-bit mono)
|
||||
# AL_FORMAT_STEREO16 (16-bit stereo)
|
||||
# AL_FORMAT_QUAD16 (16-bit 4-channel)
|
||||
# AL_FORMAT_51CHN16 (16-bit 5.1 output)
|
||||
# AL_FORMAT_61CHN16 (16-bit 6.1 output)
|
||||
# AL_FORMAT_71CHN16 (16-bit 7.1 output)
|
||||
# AL_FORMAT_MONO32 (32-bit float mono)
|
||||
# AL_FORMAT_STEREO32 (32-bit float stereo)
|
||||
# AL_FORMAT_QUAD32 (32-bit float 4-channel)
|
||||
# AL_FORMAT_51CHN32 (32-bit float 5.1 output)
|
||||
# AL_FORMAT_61CHN32 (32-bit float 6.1 output)
|
||||
# AL_FORMAT_71CHN32 (32-bit float 7.1 output)
|
||||
#format = AL_FORMAT_STEREO16
|
||||
|
||||
cf_level = 0 # Sets the crossfeed level for stereo output. Valid values are:
|
||||
# 0 - No crossfeed
|
||||
# 1 - Low crossfeed
|
||||
# 2 - Middle crossfeed
|
||||
# 3 - High crossfeed (virtual speakers are closer to itself)
|
||||
# 4 - Low easy crossfeed
|
||||
# 5 - Middle easy crossfeed
|
||||
# 6 - High easy crossfeed
|
||||
# Default is 0. Users of headphones may want to try various
|
||||
# settings. Has no effect on non-stereo modes.
|
||||
## cf_level:
|
||||
# Sets the crossfeed level for stereo output. Valid values are:
|
||||
# 0 - No crossfeed
|
||||
# 1 - Low crossfeed
|
||||
# 2 - Middle crossfeed
|
||||
# 3 - High crossfeed (virtual speakers are closer to itself)
|
||||
# 4 - Low easy crossfeed
|
||||
# 5 - Middle easy crossfeed
|
||||
# 6 - High easy crossfeed
|
||||
# Users of headphones may want to try various settings. Has no effect on non-
|
||||
# stereo modes.
|
||||
#cf_level = 0
|
||||
|
||||
frequency = 44100 # Sets the output frequency. Default is 44100
|
||||
## frequency:
|
||||
# Sets the output frequency.
|
||||
#frequency = 44100
|
||||
|
||||
refresh = 4096 # Sets the buffer size, in frames. Default is 4096. Note that
|
||||
# the actual granularity may or may not be less than this.
|
||||
## period_size:
|
||||
# Sets the update period size, in frames. This is the number of frames needed
|
||||
# for each mixing update. If the deprecated 'refresh' option is specified and
|
||||
# this isn't, the value will be calculated as size = refresh/periods.
|
||||
#period_size = 1024
|
||||
|
||||
sources = 256 # Sets the maximum number of allocatable sources. Lower values
|
||||
# may help for systems with apps that try to play more sounds
|
||||
# than the CPU can handle. Default is 256
|
||||
## periods:
|
||||
# Sets the number of update periods. Higher values create a larger mix ahead,
|
||||
# which helps protect against skips when the CPU is under load, but increases
|
||||
# the delay between a sound getting mixed and being heard.
|
||||
#periods = 4
|
||||
|
||||
stereodup = # Sets whether to duplicate stereo sounds on the rear speakers for
|
||||
# 4+ channel output. This can make stereo sources substantially
|
||||
# louder than mono or even 4+ channel sources, but provides a
|
||||
# "fuller" playback quality. True, yes, on, and non-0 values will
|
||||
# duplicate stereo sources. 0 and anything else will cause stereo
|
||||
# sounds to only play out the front speakers.
|
||||
# Default is false
|
||||
## sources:
|
||||
# Sets the maximum number of allocatable sources. Lower values may help for
|
||||
# systems with apps that try to play more sounds than the CPU can handle.
|
||||
#sources = 256
|
||||
|
||||
drivers = # Sets the backend driver list order, comma-seperated. Unknown
|
||||
# backends and duplicated names are ignored, and unlisted backends
|
||||
# won't be considered for use. An empty list means the default.
|
||||
# Default is:
|
||||
# alsa,oss,solaris,dsound,winmm,wave
|
||||
## stereodup:
|
||||
# Sets whether to duplicate stereo sounds on the rear and side speakers for 4+
|
||||
# channel output. This can make stereo sources substantially louder than mono
|
||||
# or even 4+ channel sources, but provides a "fuller" playback quality. True,
|
||||
# yes, on, and non-0 values will duplicate stereo sources. 0 and anything else
|
||||
# will cause stereo sounds to only play out the front speakers.
|
||||
#stereodup = false
|
||||
|
||||
excludefx = # Sets which effects to exclude, preventing apps from using them.
|
||||
# This can help for apps that try to use effects which are too CPU
|
||||
# intensive for the system to handle. Available effects are:
|
||||
# reverb
|
||||
# Default is empty (all available effects enabled)
|
||||
## drivers:
|
||||
# Sets the backend driver list order, comma-seperated. Unknown backends and
|
||||
# duplicated names are ignored, and unlisted backends won't be considered for
|
||||
# use. An empty list means the default.
|
||||
#drivers = alsa,oss,solaris,dsound,winmm,port,pulse,wave
|
||||
|
||||
[alsa] # ALSA backend stuff
|
||||
device = default # Sets the device name for the default playback device.
|
||||
# Default is default
|
||||
## excludefx:
|
||||
# Sets which effects to exclude, preventing apps from using them. This can
|
||||
# help for apps that try to use effects which are too CPU intensive for the
|
||||
# system to handle. Available effects are: eaxreverb,reverb,echo
|
||||
#excludefx =
|
||||
|
||||
periods = 0 # Sets the number of update buffers for playback. A value of 0
|
||||
# means auto-select. Default is 0
|
||||
## slots:
|
||||
# Sets the maximum number of Auxiliary Effect Slots an app can create. A slot
|
||||
# can use a non-negligible amount of CPU time if an effect is set on it even
|
||||
# if no sources are feeding it, so this may help when apps use more than the
|
||||
# system can handle.
|
||||
#slots = 4
|
||||
|
||||
capture = default # Sets the device name for the default capture device.
|
||||
# Default is default
|
||||
## sends:
|
||||
# Sets the maximum number of auxiliary sends per source. The total number of
|
||||
# sends possible is defined at compile time and thus can not be increased
|
||||
# beyond the default (2).
|
||||
#sends = 2
|
||||
|
||||
mmap = true # Sets whether to try using mmap mode (helps reduce latencies and
|
||||
# CPU consumption). If mmap isn't available, it will automatically
|
||||
# fall back to non-mmap mode. True, yes, on, and non-0 values will
|
||||
# attempt to use mmap. 0 and anything else will force mmap off.
|
||||
# Default is true.
|
||||
## layout_STEREO:
|
||||
# Sets the speaker layout when using stereo output. Values are specified in
|
||||
# degrees, where 0 is straight in front, negative goes left, and positive goes
|
||||
# right. The values must define a circular pattern, starting with the back-
|
||||
# left at the most negative, around the front to back-center. Unspecified
|
||||
# speakers will remain at their default position. Available speakers are
|
||||
# front-left(fl) and front-right(fr).
|
||||
#layout_STEREO = fl=-90, fr=90
|
||||
|
||||
[oss] # OSS backend stuff
|
||||
device = /dev/dsp # Sets the device name for OSS output. Default is /dev/dsp
|
||||
## laytout_QUAD:
|
||||
# Sets the speaker layout when using quadriphonic output. Available speakers
|
||||
# are back-left(bl), front-left(fl), front-right(fr), and back-right(br).
|
||||
#layout_QUAD = bl=-135, fl=-45, fr=45, br=135
|
||||
|
||||
periods = 4 # Sets the number of update buffers. Default is 4
|
||||
## layout_51CHN:
|
||||
# Sets the speaker layout when using 5.1 output. Available speakers are back-
|
||||
# left(bl), front-left(fl), front-center(fc), front-right(fr), and back-
|
||||
# right(br).
|
||||
#layout_51CHN = bl=-110, fl=-30, fc=0, fr=30, br=110
|
||||
|
||||
capture = /dev/dsp # Sets the device name for OSS capture. Default is /dev/dsp
|
||||
## layout_61CHN:
|
||||
# Sets the speaker layout when using 6.1 output. Available speakers are side-
|
||||
# left(sl), front-left(fl), front-center(fc), front-right(fr), side-right(sr),
|
||||
# and back-center(bc).
|
||||
#layout_61CHN = sl=-90, fl=-30, fc=0, fr=30, sr=90, bc=180
|
||||
|
||||
[solaris] # Solaris backend stuff
|
||||
device = /dev/audio # Sets the device name for Solaris output. Default is
|
||||
# /dev/audio
|
||||
## layout_71CHN:
|
||||
# Sets the speaker layout when using 7.1 output. Available speakers are back-
|
||||
# left(bl), side-left(sl), front-left(fl), front-center(fc), front-right(fr),
|
||||
# side-right(sr), and back-right(br).
|
||||
#layout_71CHN = bl=-150, sl=-90, fl=-30, fc=0, fr=30, sr=90, br=150
|
||||
|
||||
[dsound] # DirectSound backend stuff
|
||||
periods = 4 # Sets the number of updates for the output buffer. Default is 4
|
||||
##
|
||||
## ALSA backend stuff
|
||||
##
|
||||
[alsa]
|
||||
|
||||
[winmm] # Windows Multimedia backend stuff
|
||||
# Nothing yet...
|
||||
## device:
|
||||
# Sets the device name for the default playback device.
|
||||
#device = default
|
||||
|
||||
[wave] # Wave File Writer stuff
|
||||
file = # Sets the filename of the wave file to write to. An empty name
|
||||
# prevents the backend from opening, even when explicitly requested.
|
||||
# THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION!
|
||||
# Default is empty
|
||||
## capture:
|
||||
# Sets the device name for the default capture device.
|
||||
#capture = default
|
||||
|
||||
## mmap:
|
||||
# Sets whether to try using mmap mode (helps reduce latencies and CPU
|
||||
# consumption). If mmap isn't available, it will automatically fall back to
|
||||
# non-mmap mode. True, yes, on, and non-0 values will attempt to use mmap. 0
|
||||
# and anything else will force mmap off.
|
||||
#mmap = true
|
||||
|
||||
##
|
||||
## OSS backend stuff
|
||||
##
|
||||
[oss]
|
||||
|
||||
## device:
|
||||
# Sets the device name for OSS output.
|
||||
#device = /dev/dsp
|
||||
|
||||
## capture:
|
||||
# Sets the device name for OSS capture.
|
||||
#capture = /dev/dsp
|
||||
|
||||
##
|
||||
## Solaris backend stuff
|
||||
##
|
||||
[solaris]
|
||||
|
||||
## device:
|
||||
# Sets the device name for Solaris output.
|
||||
#device = /dev/audio
|
||||
|
||||
##
|
||||
## DirectSound backend stuff
|
||||
##
|
||||
[dsound]
|
||||
|
||||
##
|
||||
## Windows Multimedia backend stuff
|
||||
##
|
||||
[winmm]
|
||||
|
||||
##
|
||||
## PortAudio backend stuff
|
||||
##
|
||||
[port]
|
||||
|
||||
## device:
|
||||
# Sets the device index for output. Negative values will use the default as
|
||||
# given by PortAudio itself.
|
||||
#device = -1
|
||||
|
||||
##
|
||||
## PulseAudio backend stuff
|
||||
##
|
||||
[pulse]
|
||||
|
||||
##
|
||||
## Wave File Writer stuff
|
||||
##
|
||||
[wave]
|
||||
|
||||
## file:
|
||||
# Sets the filename of the wave file to write to. An empty name prevents the
|
||||
# backend from opening, even when explicitly requested.
|
||||
# THIS WILL OVERWRITE EXISTING FILES WITHOUT QUESTION!
|
||||
#file =
|
||||
|
||||
+12
@@ -19,6 +19,12 @@
|
||||
/* Define if we have the Windows Multimedia backend */
|
||||
#cmakedefine HAVE_WINMM
|
||||
|
||||
/* Define if we have the PortAudio backend */
|
||||
#cmakedefine HAVE_PORTAUDIO
|
||||
|
||||
/* Define if we have the PulseAudio backend */
|
||||
#cmakedefine HAVE_PULSEAUDIO
|
||||
|
||||
/* Define if we have dlfcn.h */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
|
||||
@@ -28,6 +34,12 @@
|
||||
/* Define if we have the acosf function */
|
||||
#cmakedefine HAVE_ACOSF
|
||||
|
||||
/* Define if we have the atanf function */
|
||||
#cmakedefine HAVE_ATANF
|
||||
|
||||
/* Define if we have the fabsf function */
|
||||
#cmakedefine HAVE_FABSF
|
||||
|
||||
/* Define if we have the strtof function */
|
||||
#cmakedefine HAVE_STRTOF
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ static void printEFXInfo(void)
|
||||
const char *name;
|
||||
} effects[] = {
|
||||
{ AL_EFFECT_EAXREVERB, "EAX Reverb" },
|
||||
{ AL_EFFECT_REVERB, "Standard Reverb" },
|
||||
{ AL_EFFECT_REVERB, "Reverb" },
|
||||
{ AL_EFFECT_CHORUS, "Chorus" },
|
||||
{ AL_EFFECT_DISTORTION, "Distortion" },
|
||||
{ AL_EFFECT_ECHO, "Echo" },
|
||||
|
||||
@@ -99,6 +99,57 @@ extern "C" {
|
||||
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATAEXTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_BUFFER_DATA_STATIC
|
||||
#define AL_EXT_BUFFER_DATA_STATIC 1
|
||||
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_sample_buffer_object
|
||||
#define AL_EXT_sample_buffer_object 1
|
||||
#define AL_SAMPLE_SOURCE_EXT 0x1040
|
||||
#define AL_SAMPLE_SINK_EXT 0x1041
|
||||
#define AL_READ_ONLY_EXT 0x1042
|
||||
#define AL_WRITE_ONLY_EXT 0x1043
|
||||
#define AL_READ_WRITE_EXT 0x1044
|
||||
#define AL_STREAM_WRITE_EXT 0x1045
|
||||
#define AL_STREAM_READ_EXT 0x1046
|
||||
#define AL_STREAM_COPY_EXT 0x1047
|
||||
#define AL_STATIC_WRITE_EXT 0x1048
|
||||
#define AL_STATIC_READ_EXT 0x1049
|
||||
#define AL_STATIC_COPY_EXT 0x104A
|
||||
#define AL_DYNAMIC_WRITE_EXT 0x104B
|
||||
#define AL_DYNAMIC_READ_EXT 0x104C
|
||||
#define AL_DYNAMIC_COPY_EXT 0x104D
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGENDATABUFFERSEXTPROC)(ALsizei n,ALuint *puiBuffers);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDELETEDATABUFFERSEXTPROC)(ALsizei n, const ALuint *puiBuffers);
|
||||
typedef ALboolean (AL_APIENTRY*PFNALISDATABUFFEREXTPROC)(ALuint uiBuffer);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERDATAEXTPROC)(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, const ALvoid *);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, ALvoid *);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat flValue);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, const ALfloat* flValues);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint lValue);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, const ALint* plValues);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat *pflValue);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, ALfloat* pflValues);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint *plValue);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, ALint* plValues);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALSELECTDATABUFFEREXTPROC)(ALenum target, ALuint uiBuffer);
|
||||
typedef ALvoid* (AL_APIENTRY*PFNALMAPDATABUFFEREXTPROC)(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
|
||||
typedef ALvoid (AL_APIENTRY*PFNALUNMAPDATABUFFEREXTPROC)(ALuint uiBuffer);
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_disconnect
|
||||
#define ALC_EXT_disconnect 1
|
||||
#define ALC_CONNECTED 0x313
|
||||
#endif
|
||||
|
||||
#ifndef ALC_EXT_thread_local_context
|
||||
#define ALC_EXT_thread_local_context 1
|
||||
typedef ALCboolean (ALCAPIENTRY*PFNALCMAKECURRENTPROC)(ALCcontext *context);
|
||||
typedef ALCcontext* (ALCAPIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user