Compare commits

...

54 Commits

Author SHA1 Message Date
Chris Robinson 2ae9da696a Release 1.4.272 2008-06-04 20:47:20 -07:00
Chris Robinson 376997c3ef Fix config value check 2008-06-04 20:44:51 -07:00
Chris Robinson e963782b8c Release 1.4.270 2008-06-04 19:46:31 -07:00
Chris Robinson 86c01aa62c Install openal-info if it is built 2008-06-04 19:40:52 -07:00
Chris Robinson 15783d25e7 Don't override the format config option in DSound 2008-06-04 18:33:02 -07:00
Chris Robinson 3243f69f21 Use %AppData%\alsoft.ini for the config file in Windows 2008-06-04 18:09:21 -07:00
Chris Robinson 10a87f510c Protect RingBufferSize calculation with the mutex 2008-06-04 17:01:44 -07:00
Chris Robinson ca6feeda29 Make sure the lib is initialized when shutting down
Pretty ugly, but the destructor sequence relies in the mutex being initialized
2008-05-18 20:17:31 -07:00
Chris Robinson cecf778de3 Add addiitonal copyright line 2008-05-18 18:44:17 -07:00
Chris Robinson fe79ab351a Add a simple example that prints out some OpenAL info 2008-05-18 18:40:53 -07:00
Chris Robinson dc0a3a6653 Remove -fno-strict-aliasing as the code should be safe, now 2008-05-18 17:46:45 -07:00
Chris Robinson fed346c285 Fix source calculations for AL_SOURCE_RELATIVE mode
Make sure the source position and direction are properly put into listener-
space before working with them, and don't calculate the listener velocity for
relative coordinates
2008-05-18 16:52:38 -07:00
Chris Robinson cad9b367a5 Use pthread_mutexattr_setkind_np as a fallback to set a recursive mutex type
Some systems (FreeBSD) don't like setting it through pthread_mutexattr_settype
2008-05-15 21:35:51 -07:00
Chris Robinson 6e86146a25 Prepare the ALSA PCM handle before starting capture
Thanks to Jason Daly for pointing it out
2008-05-06 16:05:36 -07:00
Chris Robinson 49d9695ad9 Check the right struct member for the filter type 2008-04-12 07:25:18 -07:00
Chris Robinson e15bc6b9ba Fill the correct capture device list 2008-04-05 20:33:19 -07:00
Chris Robinson 28093a6dcb constify the pointer that holds the filename 2008-03-22 19:05:00 -07:00
Chris Robinson 2af5498804 Define _WIN32_WINNT to 0x0500 when including windows.h
VC7 appears to require that value, or higher, set and fails otherwise
2008-03-01 01:39:42 -08:00
Chris Robinson 2b42d7fdb8 Don't start the DSound playback thread is startup failed 2008-03-01 00:57:37 -08:00
Chris Robinson 9b3c4faa34 Release 1.3.253 2008-02-21 01:28:18 -08:00
Chris Robinson 847b3e8b61 Preserve data and position when reallocating the reverb effect
Still not perfect, but better for when the size doesn't change
2008-02-18 21:58:58 -08:00
Chris Robinson b1bdd7c89f Add the first card after making sure there's a useable device on it 2008-02-15 21:48:00 -08:00
Chris Robinson ffe7a11866 Avoid a static variable for enumerating 2008-02-15 21:09:19 -08:00
Chris Robinson 8c3188bc7d Remove FrameSize struct member 2008-02-14 22:05:56 -08:00
Chris Robinson 880196e5a8 Remove unneeded headers 2008-02-13 19:42:47 -08:00
Chris Robinson d523b440e3 Wait for a PCM handle to be ready for more data instead of polling every 1ms or so 2008-02-13 19:34:47 -08:00
Chris Robinson f2875d5d13 Read in chunks of the fragment size, not expected buffer size 2008-02-12 21:19:09 -08:00
Chris Robinson b0720333cc UpdateSize is not used for capture devices 2008-02-12 19:50:49 -08:00
Chris Robinson c3446a10fa Rename UpdateFreq device field to UpdateSize 2008-02-12 19:38:27 -08:00
Chris Robinson fbc869eed7 Pretend DSound buffer fragment size is 1/4th the total buffer size 2008-02-12 19:24:08 -08:00
Chris Robinson e3e4dbbccf Make the backend list static 2008-02-11 17:24:04 -08:00
Chris Robinson 7fda645b16 Call InitAL at the start of some more ALC functions 2008-02-11 17:23:31 -08:00
Chris Robinson ec7f20644d Fast float-to-int function is no longer needed 2008-02-08 21:03:48 -08:00
Chris Robinson 3d5fa91703 Remove unnecessary casting 2008-02-08 21:01:05 -08:00
Chris Robinson e8acfb069c Remove explicit dependancy on ole32 and unused dxguid 2008-02-08 20:56:45 -08:00
Chris Robinson 4c38ed272d Enumerate DirectSound devices 2008-02-08 20:46:34 -08:00
Chris Robinson acbb4f8e6c Include alext.h instead of redefining some enums 2008-02-08 19:55:51 -08:00
Chris Robinson 13a3fe8a7a Remove unneeded device struct member 2008-02-08 19:41:47 -08:00
Chris Robinson 3dd3cd4ceb Prevent overflow of the device lists 2008-02-08 15:33:26 -08:00
Chris Robinson 80fcbc8adc Use all capture devices listed by ALSA, not just the first on each card 2008-02-08 15:22:17 -08:00
Chris Robinson 33680accea Don't remove the devices from the device list on unexpected shutdown
The close functions will remove it for us
2008-02-08 14:44:05 -08:00
Chris Robinson 081e593e2b Set the done flag immediately when entering the initialization
To prevent two threads from initializing at the same time (not that it's
likely to happen at this point).
2008-02-06 22:22:29 -08:00
Chris Robinson b4ffdfab81 Add an option for duplicating stereo sources on the back speakers 2008-02-06 22:18:50 -08:00
Chris Robinson 1ea4aac799 Add an alext.h header 2008-02-06 20:53:00 -08:00
Chris Robinson 4d6c292757 Fix race condition when starting winmm message poll thread 2008-02-03 00:28:00 -08:00
Chris Robinson 655a83c5c5 Use WAVEFORMATEXTENSIBLE for multichannel dsound output, and don't create a primary buffer 2008-02-01 08:17:57 -08:00
Chris Robinson e8b576bc25 Use the correct channel ordering for Windows 2008-01-27 07:04:13 -08:00
Chris Robinson 01404ed7af Fix output channel order for 6.1 and 7.1 2008-01-27 06:49:48 -08:00
Chris Robinson ad6237f6f7 Fix availibility amount calculation 2008-01-26 21:10:55 -08:00
Chris Robinson d06c64e1c4 aluBytesFromFormat returns bytes, not bits 2008-01-26 21:09:08 -08:00
Chris Robinson b4ad3186dd Update frame size after detecting the directsound output format 2008-01-25 17:05:14 -08:00
Chris Robinson 5f1c0450b3 Remove unnecessary Channels field 2008-01-25 16:38:37 -08:00
Chris Robinson 04b62f77e3 Set the output format according to the speaker setup reported by directsound 2008-01-25 05:02:00 -08:00
Chris Robinson 029dff3f40 Use both write pointers from the directsound buffer lock 2008-01-25 04:42:44 -08:00
18 changed files with 797 additions and 312 deletions
+49 -34
View File
@@ -46,7 +46,7 @@ char _alDebug[256];
#define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
struct {
static struct {
const char *name;
void (*Init)(BackendFuncs*);
BackendFuncs Funcs;
@@ -201,7 +201,9 @@ static void InitAL(void)
if(!done)
{
int i;
const char *devs;
const char *devs, *str;
done = 1;
InitializeCriticalSection(&_alMutex);
ALTHUNK_INIT();
@@ -249,31 +251,51 @@ static void InitAL(void)
for(i = 0;BackendList[i].Init;i++)
BackendList[i].Init(&BackendList[i].Funcs);
done = 1;
str = GetConfigValue(NULL, "stereodup", "false");
DuplicateStereo = (strcasecmp(str, "true") == 0 ||
strcasecmp(str, "yes") == 0 ||
strcasecmp(str, "on") == 0 ||
atoi(str) != 0);
}
}
ALCchar *AppendDeviceList(char *name)
{
static int pos;
static size_t pos;
ALCchar *ret = alcDeviceList+pos;
pos += snprintf(alcDeviceList+pos, sizeof(alcDeviceList)-pos, "%s", name) + 1;
if(pos >= sizeof(alcDeviceList))
{
AL_PRINT("Not enough room to add %s!\n", name);
return alcDeviceList + sizeof(alcDeviceList) - 1;
}
pos += snprintf(alcDeviceList+pos, sizeof(alcDeviceList)-pos-1, "%s", name) + 1;
return ret;
}
ALCchar *AppendAllDeviceList(char *name)
{
static int pos;
static size_t pos;
ALCchar *ret = alcAllDeviceList+pos;
pos += snprintf(alcAllDeviceList+pos, sizeof(alcAllDeviceList)-pos, "%s", name) + 1;
if(pos >= sizeof(alcAllDeviceList))
{
AL_PRINT("Not enough room to add %s!\n", name);
return alcAllDeviceList + sizeof(alcAllDeviceList) - 1;
}
pos += snprintf(alcAllDeviceList+pos, sizeof(alcAllDeviceList)-pos-1, "%s", name) + 1;
return ret;
}
ALCchar *AppendCaptureDeviceList(char *name)
{
static int pos;
static size_t pos;
ALCchar *ret = alcCaptureDeviceList+pos;
pos += snprintf(alcCaptureDeviceList+pos, sizeof(alcCaptureDeviceList)-pos, "%s", name) + 1;
if(pos >= sizeof(alcCaptureDeviceList))
{
AL_PRINT("Not enough room to add %s!\n", name);
return alcCaptureDeviceList + sizeof(alcCaptureDeviceList) - 1;
}
pos += snprintf(alcCaptureDeviceList+pos, sizeof(alcCaptureDeviceList)-pos-1, "%s", name) + 1;
return ret;
}
@@ -425,14 +447,10 @@ ALCAPI ALCdevice* ALCAPIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, AL
memset(pDevice, 0, sizeof(ALCdevice));
//Validate device
pDevice->InUse = AL_TRUE;
pDevice->IsCaptureDevice = AL_TRUE;
pDevice->Frequency = frequency;
pDevice->Format = format;
pDevice->Channels = aluChannelsFromFormat(format);
pDevice->FrameSize = aluBytesFromFormat(format) *
pDevice->Channels;
for(i = 0;BackendList[i].Init;i++)
{
@@ -733,7 +751,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsize
data[i++] = device->Frequency;
data[i++] = ALC_REFRESH;
data[i++] = device->Frequency / device->UpdateFreq;
data[i++] = device->Frequency / device->UpdateSize;
data[i++] = ALC_SYNC;
data[i++] = ALC_FALSE;
@@ -771,7 +789,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcGetIntegerv(ALCdevice *device,ALCenum param,ALsize
else if(!size)
SetALCError(ALC_INVALID_VALUE);
else
*data = device->Frequency / device->UpdateFreq;
*data = device->Frequency / device->UpdateSize;
break;
case ALC_SYNC:
@@ -986,6 +1004,8 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
{
ALCcontext **list;
InitAL();
// Lock context list
SuspendContext(NULL);
@@ -1031,6 +1051,8 @@ ALCAPI ALCcontext * ALCAPIENTRY alcGetCurrentContext(ALCvoid)
{
ALCcontext *pContext = NULL;
InitAL();
SuspendContext(NULL);
pContext = g_pContextList;
@@ -1052,6 +1074,8 @@ ALCAPI ALCdevice* ALCAPIENTRY alcGetContextsDevice(ALCcontext *pContext)
{
ALCdevice *pDevice = NULL;
InitAL();
SuspendContext(NULL);
if (IsContext(pContext))
pDevice = pContext->Device;
@@ -1073,6 +1097,8 @@ ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context)
ALCcontext *ALContext;
ALboolean bReturn = AL_TRUE;
InitAL();
SuspendContext(NULL);
// context must be a valid Context or NULL
@@ -1129,7 +1155,6 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
memset(device, 0, sizeof(ALCdevice));
//Validate device
device->InUse = AL_TRUE;
device->IsCaptureDevice = AL_FALSE;
//Set output format
@@ -1141,20 +1166,12 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
if(fmt[0])
device->Format = alGetEnumValue(fmt);
device->Channels = aluChannelsFromFormat(device->Format);
if(!device->Channels)
{
if(!aluChannelsFromFormat(device->Format))
device->Format = AL_FORMAT_STEREO16;
device->Channels = 2;
device->FrameSize = 4;
}
else
device->FrameSize = aluBytesFromFormat(device->Format) *
device->Channels;
device->UpdateFreq = GetConfigValueInt(NULL, "refresh", 8192);
if((ALint)device->UpdateFreq <= 0)
device->UpdateFreq = 8192;
device->UpdateSize = GetConfigValueInt(NULL, "refresh", 8192);
if((ALint)device->UpdateSize <= 0)
device->UpdateSize = 8192;
device->MaxNoOfSources = GetConfigValueInt(NULL, "sources", 256);
if((ALint)device->MaxNoOfSources <= 0)
@@ -1231,7 +1248,7 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
ALCvoid ReleaseALC(ALCvoid)
{
ALCdevice *Dev;
InitAL();
#ifdef _DEBUG
if(g_ulContextCount > 0)
@@ -1240,12 +1257,10 @@ ALCvoid ReleaseALC(ALCvoid)
while(g_pDeviceList)
{
Dev = g_pDeviceList;
g_pDeviceList = g_pDeviceList->next;
if(Dev->IsCaptureDevice)
alcCaptureCloseDevice(Dev);
if(g_pDeviceList->IsCaptureDevice)
alcCaptureCloseDevice(g_pDeviceList);
else
alcCloseDevice(Dev);
alcCloseDevice(g_pDeviceList);
}
}
+103 -60
View File
@@ -82,6 +82,8 @@ enum {
OUTPUTCHANNELS
};
ALboolean DuplicateStereo = AL_FALSE;
/* NOTE: The AL_FORMAT_REAR* enums aren't handled here be cause they're
* converted to AL_FORMAT_QUAD* when loaded */
__inline ALuint aluBytesFromFormat(ALenum format)
@@ -160,24 +162,12 @@ __inline ALuint aluChannelsFromFormat(ALenum format)
}
}
static __inline ALint aluF2L(ALfloat Value)
{
#if 0
if(sizeof(ALint) == 4 && sizeof(double) == 8)
{
double temp;
temp = Value + (((65536.0*65536.0*16.0)+(65536.0*65536.0*8.0))*65536.0);
return *((ALint*)&temp);
}
#endif
return (ALint)Value;
}
static __inline ALshort aluF2S(ALfloat Value)
{
ALint i;
i = aluF2L(Value);
i = (ALint)Value;
i = __min( 32767, i);
i = __max(-32768, i);
return ((ALshort)i);
@@ -200,8 +190,8 @@ static __inline ALvoid aluNormalize(ALfloat *inVector)
{
ALfloat length, inverse_length;
length = (ALfloat)aluSqrt(aluDotproduct(inVector, inVector));
if(length != 0)
length = aluSqrt(aluDotproduct(inVector, inVector));
if(length != 0.0f)
{
inverse_length = 1.0f/length;
inVector[0] *= inverse_length;
@@ -285,10 +275,26 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
//1. Translate Listener to origin (convert to head relative)
if(ALSource->bHeadRelative==AL_FALSE)
{
// Build transform matrix
aluCrossproduct(ALContext->Listener.Forward, ALContext->Listener.Up, U); // Right-vector
aluNormalize(U); // Normalized Right-vector
memcpy(V, ALContext->Listener.Up, sizeof(V)); // Up-vector
aluNormalize(V); // Normalized Up-vector
memcpy(N, ALContext->Listener.Forward, sizeof(N)); // At-vector
aluNormalize(N); // Normalized At-vector
Matrix[0][0] = U[0]; Matrix[0][1] = V[0]; Matrix[0][2] = -N[0];
Matrix[1][0] = U[1]; Matrix[1][1] = V[1]; Matrix[1][2] = -N[1];
Matrix[2][0] = U[2]; Matrix[2][1] = V[2]; Matrix[2][2] = -N[2];
// Translate source position into listener space
Position[0] -= ALContext->Listener.Position[0];
Position[1] -= ALContext->Listener.Position[1];
Position[2] -= ALContext->Listener.Position[2];
// Transform source position and direction into listener space
aluMatrixVector(Position, Matrix);
aluMatrixVector(Direction, Matrix);
}
aluNormalize(Direction);
//2. Calculate distance attenuation
Distance = aluSqrt(aluDotproduct(Position, Position));
@@ -369,8 +375,8 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
SourceToListener[0] = -Position[0];
SourceToListener[1] = -Position[1];
SourceToListener[2] = -Position[2];
aluNormalize(Direction);
aluNormalize(SourceToListener);
Angle = aluAcos(aluDotproduct(Direction,SourceToListener)) * 180.0f /
3.141592654f;
if(Angle >= InnerAngle && Angle <= OuterAngle)
@@ -400,10 +406,10 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
//4. Calculate Velocity
if(DopplerFactor != 0.0f)
{
ALfloat flVSS, flVLS;
ALfloat flVSS, flVLS = 0.0f;
flVLS = aluDotproduct(ALContext->Listener.Velocity,
SourceToListener);
if(ALSource->bHeadRelative==AL_FALSE)
flVLS = aluDotproduct(ALContext->Listener.Velocity, SourceToListener);
flVSS = aluDotproduct(ALSource->vVelocity, SourceToListener);
flMaxVelocity = (DopplerVelocity * flSpeedOfSound) / DopplerFactor;
@@ -425,20 +431,8 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
else
pitch[0] = ALSource->flPitch;
//5. Align coordinate system axes
aluCrossproduct(ALContext->Listener.Forward, ALContext->Listener.Up, U); // Right-vector
aluNormalize(U); // Normalized Right-vector
memcpy(V, ALContext->Listener.Up, sizeof(V)); // Up-vector
aluNormalize(V); // Normalized Up-vector
memcpy(N, ALContext->Listener.Forward, sizeof(N)); // At-vector
aluNormalize(N); // Normalized At-vector
Matrix[0][0] = U[0]; Matrix[0][1] = V[0]; Matrix[0][2] = -N[0];
Matrix[1][0] = U[1]; Matrix[1][1] = V[1]; Matrix[1][2] = -N[1];
Matrix[2][0] = U[2]; Matrix[2][1] = V[2]; Matrix[2][2] = -N[2];
aluMatrixVector(Position, Matrix);
//6. Apply filter gains and filters
switch(ALSource->DirectFilter.filter)
//5. Apply filter gains and filters
switch(ALSource->DirectFilter.type)
{
case AL_FILTER_LOWPASS:
DryMix *= ALSource->DirectFilter.Gain;
@@ -446,7 +440,7 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
break;
}
switch(ALSource->Send[0].WetFilter.filter)
switch(ALSource->Send[0].WetFilter.type)
{
case AL_FILTER_LOWPASS:
WetMix *= ALSource->Send[0].WetFilter.Gain;
@@ -478,7 +472,7 @@ static ALvoid CalcSourceParams(ALCcontext *ALContext, ALsource *ALSource,
DryMix *= ListenerGain * ConeVolume;
WetMix *= ListenerGain;
//7. Convert normalized position into pannings, then into channel volumes
//6. Convert normalized position into pannings, then into channel volumes
aluNormalize(Position);
switch(aluChannelsFromFormat(OutputFormat))
{
@@ -676,7 +670,7 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
WetSample = ALSource->LastWetSample;
//Compute 18.14 fixed point step
increment = aluF2L(Pitch*(1L<<FRACTIONBITS));
increment = (ALint)(Pitch*(ALfloat)(1L<<FRACTIONBITS));
if(increment > (MAX_PITCH<<FRACTIONBITS))
increment = (MAX_PITCH<<FRACTIONBITS);
@@ -752,14 +746,15 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
}
else
{
ALfloat samp1, samp2;
//First order interpolator (front left)
value = (ALfloat)((ALshort)(((Data[k*Channels ]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels ]*(fraction)))>>FRACTIONBITS));
DryBuffer[j][FRONT_LEFT] += value*DrySend[FRONT_LEFT];
WetBuffer[j][FRONT_LEFT] += value*WetSend[FRONT_LEFT];
samp1 = (ALfloat)((ALshort)(((Data[k*Channels ]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels ]*(fraction)))>>FRACTIONBITS));
DryBuffer[j][FRONT_LEFT] += samp1*DrySend[FRONT_LEFT];
WetBuffer[j][FRONT_LEFT] += samp1*WetSend[FRONT_LEFT];
//First order interpolator (front right)
value = (ALfloat)((ALshort)(((Data[k*Channels+1]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+1]*(fraction)))>>FRACTIONBITS));
DryBuffer[j][FRONT_RIGHT] += value*DrySend[FRONT_RIGHT];
WetBuffer[j][FRONT_RIGHT] += value*WetSend[FRONT_RIGHT];
samp2 = (ALfloat)((ALshort)(((Data[k*Channels+1]*((1L<<FRACTIONBITS)-fraction))+(Data[(k+1)*Channels+1]*(fraction)))>>FRACTIONBITS));
DryBuffer[j][FRONT_RIGHT] += samp2*DrySend[FRONT_RIGHT];
WetBuffer[j][FRONT_RIGHT] += samp2*WetSend[FRONT_RIGHT];
if(Channels >= 4)
{
int i = 2;
@@ -803,6 +798,14 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
i++;
}
}
else if(DuplicateStereo)
{
//Duplicate stereo channels on the back speakers
DryBuffer[j][BACK_LEFT] += samp1*DrySend[BACK_LEFT];
WetBuffer[j][BACK_LEFT] += samp1*WetSend[BACK_LEFT];
DryBuffer[j][BACK_RIGHT] += samp2*DrySend[BACK_RIGHT];
WetBuffer[j][BACK_RIGHT] += samp2*WetSend[BACK_RIGHT];
}
}
DataPosFrac += increment;
j++;
@@ -998,10 +1001,17 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
#ifdef _WIN32 /* Of course, Windows can't use the same ordering... */
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
#else
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
#endif
buffer = ((ALubyte*)buffer) + 6;
}
break;
@@ -1010,11 +1020,17 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
#ifdef _WIN32
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
#else
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
#endif
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
buffer = ((ALubyte*)buffer) + 7;
}
break;
@@ -1023,12 +1039,19 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALubyte*)buffer)[0] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT])>>8)+128);
((ALubyte*)buffer)[1] = (ALubyte)((aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT])>>8)+128);
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
#ifdef _WIN32
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
((ALubyte*)buffer)[7] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
#else
((ALubyte*)buffer)[2] = (ALubyte)((aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT])>>8)+128);
((ALubyte*)buffer)[3] = (ALubyte)((aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT])>>8)+128);
((ALubyte*)buffer)[4] = (ALubyte)((aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER])>>8)+128);
((ALubyte*)buffer)[5] = (ALubyte)((aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE])>>8)+128);
#endif
((ALubyte*)buffer)[6] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT])>>8)+128);
((ALubyte*)buffer)[7] = (ALubyte)((aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT])>>8)+128);
buffer = ((ALubyte*)buffer) + 8;
}
break;
@@ -1080,10 +1103,17 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
#ifdef _WIN32
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
#else
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
#endif
buffer = ((ALshort*)buffer) + 6;
}
break;
@@ -1092,11 +1122,17 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
#ifdef _WIN32
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
#else
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
#endif
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
buffer = ((ALshort*)buffer) + 7;
}
break;
@@ -1105,12 +1141,19 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
{
((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT] +WetBuffer[i][FRONT_LEFT]);
((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]+WetBuffer[i][FRONT_RIGHT]);
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
#ifdef _WIN32
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
((ALshort*)buffer)[7] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
#else
((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT] +WetBuffer[i][BACK_LEFT]);
((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT] +WetBuffer[i][BACK_RIGHT]);
((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][CENTER] +WetBuffer[i][CENTER]);
((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][LFE] +WetBuffer[i][LFE]);
#endif
((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][SIDE_LEFT] +WetBuffer[i][SIDE_LEFT]);
((ALshort*)buffer)[7] = aluF2S(DryBuffer[i][SIDE_RIGHT] +WetBuffer[i][SIDE_RIGHT]);
buffer = ((ALshort*)buffer) + 8;
}
break;
+16
View File
@@ -27,6 +27,11 @@
#include "alMain.h"
#ifdef _WIN32
#define _WIN32_IE 0x400
#include <shlobj.h>
#endif
typedef struct ConfigEntry {
char *key;
char *value;
@@ -201,6 +206,17 @@ void ReadALConfig(void)
cfgCount = 1;
#ifdef _WIN32
if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE)
{
int p = strlen(buffer);
snprintf(buffer+p, sizeof(buffer)-p, "\\alsoft.ini");
f = fopen(buffer, "rt");
if(f)
{
LoadConfigFromFile(f);
fclose(f);
}
}
#else
f = fopen("/etc/openal/alsoft.conf", "r");
if(!f)
+7 -2
View File
@@ -70,7 +70,13 @@ void DestroyRingBuffer(RingBuffer *ring)
ALsizei RingBufferSize(RingBuffer *ring)
{
return (ring->write_pos-ring->read_pos-1+ring->length) % ring->length;
ALsizei s;
EnterCriticalSection(&ring->cs);
s = (ring->write_pos-ring->read_pos-1+ring->length) % ring->length;
LeaveCriticalSection(&ring->cs);
return s;
}
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
@@ -115,4 +121,3 @@ void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
LeaveCriticalSection(&ring->cs);
}
-2
View File
@@ -28,8 +28,6 @@
#ifdef _WIN32
#include <windows.h>
typedef struct {
ALuint (*func)(ALvoid*);
ALvoid *ptr;
+57 -24
View File
@@ -73,6 +73,7 @@ MAKE_FUNC(snd_pcm_hw_params);
MAKE_FUNC(snd_pcm_prepare);
MAKE_FUNC(snd_pcm_start);
MAKE_FUNC(snd_pcm_resume);
MAKE_FUNC(snd_pcm_wait);
MAKE_FUNC(snd_pcm_state);
MAKE_FUNC(snd_pcm_avail_update);
MAKE_FUNC(snd_pcm_areas_silence);
@@ -102,7 +103,7 @@ MAKE_FUNC(snd_card_next);
static DevMap allDevNameMap[MAX_ALL_DEVICES];
static ALCchar *alsaDeviceList[MAX_DEVICES];
static ALCchar *alsaCaptureDeviceList[MAX_DEVICES];
static DevMap allCaptureDevNameMap[MAX_ALL_DEVICES];
static int xrun_recovery(snd_pcm_t *handle, int err)
{
@@ -185,7 +186,8 @@ static ALuint ALSAProc(ALvoid *ptr)
break;
}
}
Sleep(1);
else if(psnd_pcm_wait(data->pcmHandle, 1000) == 0)
AL_PRINT("Wait timeout... buffer size too low?\n");
continue;
}
@@ -357,7 +359,7 @@ open_alsa:
}
periods = GetConfigValueInt("alsa", "periods", 0);
bufferSizeInFrames = device->UpdateFreq;
bufferSizeInFrames = device->UpdateSize;
str = GetConfigValue("alsa", "mmap", "true");
allowmmap = (strcasecmp(str, "true") == 0 ||
@@ -375,7 +377,7 @@ open_alsa:
/* set format (implicitly sets sample bits) */
ok(psnd_pcm_hw_params_set_format(data->pcmHandle, p, data->format), "set format") &&
/* set channels (implicitly sets frame bits) */
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, device->Channels), "set channels") &&
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, aluChannelsFromFormat(device->Format)), "set channels") &&
/* set periods (implicitly constrains period/buffer parameters) */
(!periods || ok(psnd_pcm_hw_params_set_periods_near(data->pcmHandle, p, &periods, NULL), "set periods near")) &&
/* set rate (implicitly constrains period/buffer parameters) */
@@ -413,9 +415,9 @@ open_alsa:
psnd_pcm_hw_params_free(p);
device->UpdateFreq = bufferSizeInFrames;
device->UpdateSize = bufferSizeInFrames;
data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateFreq);
data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, device->UpdateSize);
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
{
data->buffer = malloc(data->size);
@@ -489,21 +491,21 @@ static ALCboolean alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceNam
{
size_t idx;
for(idx = 0;idx < MAX_DEVICES;idx++)
for(idx = 0;idx < MAX_ALL_DEVICES;idx++)
{
if(alsaCaptureDeviceList[idx] &&
strcmp(deviceName, alsaCaptureDeviceList[idx]) == 0)
if(allCaptureDevNameMap[idx].name &&
strcmp(deviceName, allCaptureDevNameMap[idx].name) == 0)
{
pDevice->szDeviceName = alsaCaptureDeviceList[idx];
pDevice->szDeviceName = allCaptureDevNameMap[idx].name;
if(idx > 0)
sprintf(driver, "hw:%zd,0", idx-1);
sprintf(driver, "hw:%d,%d", allCaptureDevNameMap[idx].card, allCaptureDevNameMap[idx].dev);
goto open_alsa;
}
}
return ALC_FALSE;
}
else
pDevice->szDeviceName = alsaCaptureDeviceList[0];
pDevice->szDeviceName = allCaptureDevNameMap[0].name;
open_alsa:
data = (alsa_data*)calloc(1, sizeof(alsa_data));
@@ -551,7 +553,7 @@ open_alsa:
/* set format (implicitly sets sample bits) */
ok(psnd_pcm_hw_params_set_format(data->pcmHandle, p, alsaFormat), "set format") &&
/* set channels (implicitly sets frame bits) */
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, pDevice->Channels), "set channels") &&
ok(psnd_pcm_hw_params_set_channels(data->pcmHandle, p, aluChannelsFromFormat(pDevice->Format)), "set channels") &&
/* set rate (implicitly constrains period/buffer parameters) */
ok(psnd_pcm_hw_params_set_rate(data->pcmHandle, p, frequency, 0), "set rate") &&
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
@@ -593,6 +595,7 @@ static void alsa_close_capture(ALCdevice *pDevice)
static void alsa_start_capture(ALCdevice *pDevice)
{
alsa_data *data = (alsa_data*)pDevice->ExtraData;
psnd_pcm_prepare(data->pcmHandle);
psnd_pcm_start(data->pcmHandle);
}
@@ -645,7 +648,7 @@ static void alsa_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint l
}
Pointer = (char*)areas->addr + (offset * areas->step / 8);
Count = size * pDevice->FrameSize;
Count = psnd_pcm_frames_to_bytes(data->pcmHandle, size);
memcpy(pBuffer, Pointer, Count);
pBuffer = (char*)pBuffer + Count;
@@ -747,6 +750,7 @@ LOAD_FUNC(snd_pcm_hw_params);
LOAD_FUNC(snd_pcm_prepare);
LOAD_FUNC(snd_pcm_start);
LOAD_FUNC(snd_pcm_resume);
LOAD_FUNC(snd_pcm_wait);
LOAD_FUNC(snd_pcm_state);
LOAD_FUNC(snd_pcm_avail_update);
LOAD_FUNC(snd_pcm_areas_silence);
@@ -786,6 +790,8 @@ LOAD_FUNC(snd_card_next);
}
while (card >= 0) {
int firstDev = 1;
sprintf(name, "hw:%d", card);
if ((err = psnd_ctl_open(&handle, name, 0)) < 0) {
AL_PRINT("control open (%i): %s\n", card, psnd_strerror(err));
@@ -796,11 +802,6 @@ LOAD_FUNC(snd_card_next);
psnd_ctl_close(handle);
goto next_card;
}
if(card < MAX_DEVICES-1) {
snprintf(name, sizeof(name), "ALSA Software on %s",
psnd_ctl_card_info_get_name(info));
alsaDeviceList[card+1] = AppendDeviceList(name);
}
dev = -1;
while (idx < MAX_ALL_DEVICES) {
@@ -810,6 +811,14 @@ LOAD_FUNC(snd_card_next);
AL_PRINT("snd_ctl_pcm_next_device failed\n");
if (dev < 0)
break;
if(firstDev && card < MAX_DEVICES-1) {
firstDev = 0;
snprintf(name, sizeof(name), "ALSA Software on %s",
psnd_ctl_card_info_get_name(info));
alsaDeviceList[card+1] = AppendDeviceList(name);
}
psnd_pcm_info_set_device(pcminfo, dev);
psnd_pcm_info_set_subdevice(pcminfo, 0);
psnd_pcm_info_set_stream(pcminfo, stream);
@@ -847,7 +856,8 @@ next_card:
return;
}
alsaCaptureDeviceList[0] = AppendCaptureDeviceList("ALSA Capture on default");
allCaptureDevNameMap[0].name = AppendCaptureDeviceList("ALSA Capture on default");
idx = 1;
while (card >= 0) {
sprintf(name, "hw:%d", card);
@@ -858,11 +868,34 @@ next_card:
if (err >= 0 && (err = psnd_ctl_card_info(handle, info)) < 0) {
AL_PRINT("control hardware info (%i): %s\n", card, psnd_strerror(err));
}
else if (err >= 0 && card < MAX_DEVICES-1)
else if (err >= 0)
{
snprintf(name, sizeof(name), "ALSA Capture on %s",
psnd_ctl_card_info_get_name(info));
alsaCaptureDeviceList[card+1] = AppendCaptureDeviceList(name);
dev = -1;
while (idx < MAX_ALL_DEVICES) {
const char *cname, *dname;
if (psnd_ctl_pcm_next_device(handle, &dev)<0)
AL_PRINT("snd_ctl_pcm_next_device failed\n");
if (dev < 0)
break;
psnd_pcm_info_set_device(pcminfo, dev);
psnd_pcm_info_set_subdevice(pcminfo, 0);
psnd_pcm_info_set_stream(pcminfo, stream);
if ((err = psnd_ctl_pcm_info(handle, pcminfo)) < 0) {
if (err != -ENOENT)
AL_PRINT("control digital audio info (%i): %s\n", card, psnd_strerror(err));
continue;
}
cname = psnd_ctl_card_info_get_name(info);
dname = psnd_pcm_info_get_name(pcminfo);
snprintf(name, sizeof(name), "ALSA Capture on %s [%s]",
cname, dname);
allCaptureDevNameMap[idx].name = AppendCaptureDeviceList(name);
allCaptureDevNameMap[idx].card = card;
allCaptureDevNameMap[idx].dev = dev;
idx++;
}
}
if(handle) psnd_ctl_close(handle);
if(psnd_card_next(&card) < 0) {
+187 -51
View File
@@ -20,18 +20,27 @@
#include "config.h"
#define _WIN32_WINNT 0x0500
#define INITGUID
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include <mmreg.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#ifndef DSSPEAKER_7POINT1
#define DSSPEAKER_7POINT1 7
#endif
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
// Since DSound doesn't report the fragment size, just assume 4 fragments
#define DS_FRAGS 4
typedef struct {
// DirectSound Playback Device
@@ -44,7 +53,11 @@ typedef struct {
} DSoundData;
static ALCchar *DeviceList[16];
typedef struct {
ALCchar *name;
GUID guid;
} DevMap;
static DevMap DeviceList[16];
static ALuint DSoundProc(ALvoid *ptr)
@@ -53,16 +66,21 @@ static ALuint DSoundProc(ALvoid *ptr)
DSoundData *pData = (DSoundData*)pDevice->ExtraData;
DWORD LastCursor = 0;
DWORD PlayCursor;
VOID *WritePtr;
DWORD WriteCnt;
VOID *WritePtr1, *WritePtr2;
DWORD WriteCnt1, WriteCnt2;
DWORD BufferSize;
DWORD avail;
HRESULT err;
BufferSize = pDevice->UpdateSize * DS_FRAGS *
aluBytesFromFormat(pDevice->Format) *
aluChannelsFromFormat(pDevice->Format);
while(!pData->killNow)
{
// Get current play and write cursors
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
avail = (PlayCursor-LastCursor) % (pDevice->UpdateFreq*pDevice->FrameSize);
avail = (PlayCursor-LastCursor+BufferSize) % BufferSize;
if(avail == 0)
{
@@ -71,8 +89,9 @@ static ALuint DSoundProc(ALvoid *ptr)
}
// Lock output buffer
WriteCnt = 0;
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr, &WriteCnt, NULL, NULL, 0);
WriteCnt1 = 0;
WriteCnt2 = 0;
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
// If the buffer is lost, restore it, play and lock
if(err == DSERR_BUFFERLOST)
@@ -81,7 +100,7 @@ static ALuint DSoundProc(ALvoid *ptr)
if(SUCCEEDED(err))
err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
if(SUCCEEDED(err))
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, (LPVOID*)&WritePtr, &WriteCnt, NULL, NULL, 0);
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
}
// Successfully locked the output buffer
@@ -89,18 +108,19 @@ static ALuint DSoundProc(ALvoid *ptr)
{
// If we have an active context, mix data directly into output buffer otherwise fill with silence
SuspendContext(NULL);
aluMixData(pDevice->Context, WritePtr, WriteCnt, pDevice->Format);
aluMixData(pDevice->Context, WritePtr1, WriteCnt1, pDevice->Format);
aluMixData(pDevice->Context, WritePtr2, WriteCnt2, pDevice->Format);
ProcessContext(NULL);
// Unlock output buffer only when successfully locked
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr, WriteCnt, NULL, 0);
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
}
else
AL_PRINT("Buffer lock error: %#lx\n", err);
// Update old write cursor location
LastCursor += WriteCnt;
LastCursor %= pDevice->UpdateFreq*pDevice->FrameSize;
LastCursor += WriteCnt1+WriteCnt2;
LastCursor %= BufferSize;
}
return 0;
@@ -110,35 +130,32 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
{
DSBUFFERDESC DSBDescription;
DSoundData *pData = NULL;
WAVEFORMATEX OutputType;
WAVEFORMATEXTENSIBLE OutputType;
DWORD frameSize = 0;
LPGUID guid = NULL;
DWORD speakers;
HRESULT hr;
if(deviceName)
{
int i;
for(i = 0;DeviceList[i];i++)
for(i = 0;DeviceList[i].name;i++)
{
if(strcmp(deviceName, DeviceList[i]) == 0)
if(strcmp(deviceName, DeviceList[i].name) == 0)
{
device->szDeviceName = DeviceList[i];
device->szDeviceName = DeviceList[i].name;
if(i > 0)
guid = &DeviceList[i].guid;
break;
}
}
if(!DeviceList[i])
if(!DeviceList[i].name)
return ALC_FALSE;
}
else
device->szDeviceName = DeviceList[0];
device->szDeviceName = DeviceList[0].name;
//Platform specific
memset(&OutputType, 0, sizeof(WAVEFORMATEX));
OutputType.wFormatTag = WAVE_FORMAT_PCM;
OutputType.nChannels = device->Channels;
OutputType.wBitsPerSample = aluBytesFromFormat(device->Format) * 8;
OutputType.nBlockAlign = OutputType.nChannels*OutputType.wBitsPerSample/8;
OutputType.nSamplesPerSec = device->Frequency;
OutputType.nAvgBytesPerSec = OutputType.nSamplesPerSec*OutputType.nBlockAlign;
OutputType.cbSize = 0;
memset(&OutputType, 0, sizeof(OutputType));
//Initialise requested device
@@ -149,43 +166,141 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
return ALC_FALSE;
}
//Init COM
CoInitialize(NULL);
//DirectSound Init code
hr = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (LPVOID*)&pData->lpDS);
if(SUCCEEDED(hr))
hr = IDirectSound_Initialize(pData->lpDS, NULL);
hr = DirectSoundCreate(guid, &pData->lpDS, NULL);
if(SUCCEEDED(hr))
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
if(SUCCEEDED(hr))
{
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
if(*(GetConfigValue(NULL, "format", "")) == 0)
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
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);
}
}
if(SUCCEEDED(hr))
hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType);
{
speakers = DSSPEAKER_CONFIG(speakers);
if(speakers == DSSPEAKER_MONO)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_MONO8;
else
device->Format = AL_FORMAT_MONO16;
}
else if(speakers == DSSPEAKER_STEREO)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_STEREO8;
else
device->Format = AL_FORMAT_STEREO16;
}
else if(speakers == DSSPEAKER_QUAD)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_QUAD8;
else
device->Format = AL_FORMAT_QUAD16;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT |
SPEAKER_BACK_RIGHT;
}
else if(speakers == DSSPEAKER_5POINT1)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_51CHN8;
else
device->Format = AL_FORMAT_51CHN16;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
SPEAKER_LOW_FREQUENCY |
SPEAKER_BACK_LEFT |
SPEAKER_BACK_RIGHT;
}
else if(speakers == DSSPEAKER_7POINT1)
{
if(aluBytesFromFormat(device->Format) == 1)
device->Format = AL_FORMAT_71CHN8;
else
device->Format = AL_FORMAT_71CHN16;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
SPEAKER_LOW_FREQUENCY |
SPEAKER_BACK_LEFT |
SPEAKER_BACK_RIGHT |
SPEAKER_SIDE_LEFT |
SPEAKER_SIDE_RIGHT;
}
frameSize = aluBytesFromFormat(device->Format) *
aluChannelsFromFormat(device->Format);
OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
OutputType.Format.nChannels = aluChannelsFromFormat(device->Format);
OutputType.Format.wBitsPerSample = aluBytesFromFormat(device->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 /= DS_FRAGS;
}
if(OutputType.Format.nChannels > 2)
{
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
OutputType.Format.cbSize = 22;
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
}
else
{
if(SUCCEEDED(hr))
{
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
}
if(SUCCEEDED(hr))
hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
}
if(SUCCEEDED(hr))
{
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
DSBDescription.dwBufferBytes=device->UpdateFreq * device->FrameSize;
DSBDescription.lpwfxFormat=&OutputType;
DSBDescription.dwBufferBytes=device->UpdateSize * DS_FRAGS * frameSize;
DSBDescription.lpwfxFormat=&OutputType.Format;
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
}
if(SUCCEEDED(hr))
hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
device->ExtraData = pData;
pData->thread = StartThread(DSoundProc, device);
if(!pData->thread)
hr = E_FAIL;
if(SUCCEEDED(hr))
{
device->ExtraData = pData;
pData->thread = StartThread(DSoundProc, device);
if(!pData->thread)
hr = E_FAIL;
}
if(FAILED(hr))
{
@@ -211,12 +326,10 @@ static void DSoundClosePlayback(ALCdevice *device)
StopThread(pData->thread);
IDirectSoundBuffer_Release(pData->DSsbuffer);
IDirectSoundBuffer_Release(pData->DSpbuffer);
if (pData->DSpbuffer)
IDirectSoundBuffer_Release(pData->DSpbuffer);
IDirectSound_Release(pData->lpDS);
//Deinit COM
CoUninitialize();
free(pData);
device->ExtraData = NULL;
}
@@ -272,10 +385,33 @@ BackendFuncs DSoundFuncs = {
DSoundAvailableSamples
};
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
{
size_t *iter = 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)++;
}
else
DeviceList[0].name = AppendDeviceList("DirectSound Software");
return TRUE;
}
void alcDSoundInit(BackendFuncs *FuncList)
{
size_t iter = 1;
HRESULT hr;
*FuncList = DSoundFuncs;
DeviceList[0] = AppendDeviceList("DirectSound Software");
AppendAllDeviceList(DeviceList[0]);
hr = DirectSoundEnumerate(DSoundEnumDevices, &iter);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
}
+26 -54
View File
@@ -149,6 +149,7 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
char driver[64];
int numChannels;
oss_data *data;
@@ -195,9 +196,11 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
periods = GetConfigValueInt("oss", "periods", 4);
if((int)periods <= 0)
periods = 4;
numChannels = device->Channels;
numChannels = aluChannelsFromFormat(device->Format);
frameSize = numChannels * aluBytesFromFormat(device->Format);
ossSpeed = device->Frequency;
log2FragmentSize = log2i(device->UpdateFreq * device->FrameSize / periods);
log2FragmentSize = log2i(device->UpdateSize * frameSize / periods);
/* according to the OSS spec, 16 bytes are the minimum */
if (log2FragmentSize < 4)
@@ -220,9 +223,9 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
device->Frequency = ossSpeed;
if((int)device->Channels != numChannels)
if((int)aluChannelsFromFormat(device->Format) != numChannels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", device->Channels, numChannels);
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), numChannels);
close(data->fd);
free(data);
return ALC_FALSE;
@@ -237,9 +240,9 @@ static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName
return ALC_FALSE;
}
device->UpdateFreq = info.fragsize / device->FrameSize;
device->UpdateSize = info.fragsize / frameSize;
data->data_size = device->UpdateFreq * device->FrameSize;
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
device->ExtraData = data;
@@ -275,6 +278,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
int numChannels;
char driver[64];
oss_data *data;
@@ -319,9 +323,10 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
}
periods = 4;
numChannels = device->Channels;
numChannels = aluChannelsFromFormat(device->Format);
frameSize = numChannels * aluBytesFromFormat(device->Format);
ossSpeed = frequency;
log2FragmentSize = log2i(device->UpdateFreq * device->FrameSize / periods);
log2FragmentSize = log2i(SampleSize * frameSize / periods);
/* according to the OSS spec, 16 bytes are the minimum */
if (log2FragmentSize < 4)
@@ -342,55 +347,24 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
}
#undef ok
device->Channels = numChannels;
device->Frequency = ossSpeed;
device->Format = 0;
if(ossFormat == AFMT_U8)
if((int)aluChannelsFromFormat(device->Format) != numChannels)
{
if(device->Channels == 1)
{
device->Format = AL_FORMAT_MONO8;
device->FrameSize = 1;
}
else if(device->Channels == 2)
{
device->Format = AL_FORMAT_STEREO8;
device->FrameSize = 2;
}
else if(device->Channels == 4)
{
device->Format = AL_FORMAT_QUAD8;
device->FrameSize = 4;
}
}
else if(ossFormat == AFMT_S16_NE)
{
if(device->Channels == 1)
{
device->Format = AL_FORMAT_MONO16;
device->FrameSize = 2;
}
else if(device->Channels == 2)
{
device->Format = AL_FORMAT_STEREO16;
device->FrameSize = 4;
}
else if(device->Channels == 4)
{
device->Format = AL_FORMAT_QUAD16;
device->FrameSize = 8;
}
}
if(!device->Format)
{
AL_PRINT("returned unknown format: %#x %d!\n", ossFormat, numChannels);
AL_PRINT("Could not set %d channels, got %d instead\n", aluChannelsFromFormat(device->Format), numChannels);
close(data->fd);
free(data);
return ALC_FALSE;
}
data->ring = CreateRingBuffer(device->FrameSize, SampleSize);
if(!((ossFormat == AFMT_U8 && aluBytesFromFormat(device->Format) == 1) ||
(ossFormat == AFMT_S16_NE && aluBytesFromFormat(device->Format) == 2)))
{
AL_PRINT("Could not set %d-bit input, got format %#x\n", aluBytesFromFormat(device->Format)*8, ossFormat);
close(data->fd);
free(data);
return ALC_FALSE;
}
data->ring = CreateRingBuffer(frameSize, SampleSize);
if(!data->ring)
{
AL_PRINT("ring buffer create failed\n");
@@ -399,9 +373,7 @@ static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName,
return ALC_FALSE;
}
device->UpdateFreq = info.fragsize / device->FrameSize;
data->data_size = device->UpdateFreq * device->FrameSize * info.fragments;
data->data_size = info.fragsize;
data->mix_data = calloc(1, data->data_size);
device->ExtraData = data;
+3 -3
View File
@@ -66,7 +66,7 @@ static ALuint WaveProc(ALvoid *ptr)
now = timeGetTime();
avail = (now-last) * pDevice->Frequency / 1000;
if(avail < pDevice->UpdateFreq/4)
if(avail < pDevice->UpdateSize/4)
{
Sleep(1);
continue;
@@ -212,9 +212,9 @@ static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceNam
data->DataStart = ftell(data->f);
device->UpdateFreq = max(device->UpdateFreq, 2048);
device->UpdateSize = max(device->UpdateSize, 2048);
data->size = device->UpdateFreq;
data->size = device->UpdateSize;
data->buffer = malloc(data->size * channels * bits / 8);
if(!data->buffer)
{
+36 -16
View File
@@ -20,6 +20,7 @@
#include "config.h"
#define _WIN32_WINNT 0x0500
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
@@ -65,7 +66,7 @@ static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,D
(void)hDevice;
(void)dwParam2;
if ((uMsg==WIM_DATA) && (pDevice))
if ((uMsg==WIM_DATA))
{
// Decrement number of buffers in use
pData->lWaveInBuffersCommitted--;
@@ -209,12 +210,13 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));
wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM;
wfexCaptureFormat.nChannels = pDevice->Channels;
wfexCaptureFormat.wBitsPerSample = pDevice->FrameSize / pDevice->Channels * 8;
wfexCaptureFormat.nBlockAlign = pDevice->FrameSize;
wfexCaptureFormat.nChannels = aluChannelsFromFormat(pDevice->Format);
wfexCaptureFormat.wBitsPerSample = aluBytesFromFormat(pDevice->Format) * 8;
wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
wfexCaptureFormat.nChannels / 8;
wfexCaptureFormat.nSamplesPerSec = frequency;
wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
pDevice->FrameSize;
wfexCaptureFormat.nBlockAlign;
wfexCaptureFormat.cbSize = 0;
if (waveInOpen(&pData->hWaveInHandle, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION) != MMSYSERR_NOERROR)
@@ -228,10 +230,6 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
if (pData->hWaveInThreadEvent == NULL)
goto failure;
pData->hWaveInThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveInThreadID);
if (pData->hWaveInThread == NULL)
goto failure;
// Allocate circular memory buffer for the captured audio
pData->ulCapturedDataSize = SampleSize * wfexCaptureFormat.nBlockAlign;
@@ -266,15 +264,32 @@ static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName
pData->ulWriteCapturedDataPos = 0;
pDevice->ExtraData = pData;
pData->hWaveInThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveInThreadID);
if (pData->hWaveInThread == NULL)
goto failure;
return ALC_TRUE;
failure:
if (pData->hWaveInThreadEvent)
CloseHandle(pData->hWaveInThreadEvent);
for (i=0;i<4;i++)
{
if(pData->WaveInBuffer[i].lpData)
{
waveInUnprepareHeader(pData->hWaveInHandle, &pData->WaveInBuffer[i], sizeof(WAVEHDR));
free(pData->WaveInBuffer[i].lpData);
}
}
free(pData->pCapturedSampleData);
if(pData->hWaveInHandle)
waveInClose(pData->hWaveInHandle);
if(pData->hWaveInThread)
CloseHandle(pData->hWaveInThread);
if (pData->hWaveInHdrEvent)
CloseHandle(pData->hWaveInHdrEvent);
if (pData->hWaveInHandle)
waveInClose(pData->hWaveInHandle);
if (pData->hWaveInThreadEvent)
CloseHandle(pData->hWaveInThreadEvent);
free(pData);
return ALC_FALSE;
@@ -348,16 +363,20 @@ static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lS
ALuint ulBytes, ulBytesToCopy;
ALuint ulCapturedSamples;
ALuint ulReadOffset;
ALuint frameSize = aluBytesFromFormat(pDevice->Format) *
aluChannelsFromFormat(pDevice->Format);
// Check that we have the requested numbers of Samples
ulCapturedSamples = (pData->ulWriteCapturedDataPos - pData->ulReadCapturedDataPos) / pDevice->FrameSize;
ulCapturedSamples = (pData->ulWriteCapturedDataPos -
pData->ulReadCapturedDataPos) /
frameSize;
if(ulSamples > ulCapturedSamples)
{
SetALCError(ALC_INVALID_VALUE);
return;
}
ulBytes = ulSamples * pDevice->FrameSize;
ulBytes = ulSamples * frameSize;
// Get Read Offset
ulReadOffset = (pData->ulReadCapturedDataPos % pData->ulCapturedDataSize);
@@ -386,7 +405,8 @@ static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
ALCuint lCapturedBytes = (pData->ulWriteCapturedDataPos - pData->ulReadCapturedDataPos);
return lCapturedBytes / pDevice->FrameSize;
return lCapturedBytes / (aluBytesFromFormat(pDevice->Format) *
aluChannelsFromFormat(pDevice->Format));
}
+29 -24
View File
@@ -22,12 +22,14 @@ OPTION(WINMM "Check for Windows Multimedia backend" ON)
OPTION(DLOPEN "Check for the dlopen API for loading optional libs" ON)
OPTION(WERROR "Treat compile warnings as errors" OFF)
OPTION(WERROR "Treat compile warnings as errors" OFF)
OPTION(EXAMPLES "Build example programs" ON)
SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "2")
SET(LIB_BUILD_VERSION "218")
SET(LIB_MINOR_VERSION "4")
SET(LIB_BUILD_VERSION "272")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}")
@@ -76,13 +78,6 @@ ELSE()
"Flags used by the compiler during debug builds."
FORCE)
# The mixer doesn't like GCC's strict aliasing optimizations. Make sure
# it's turned off
CHECK_C_COMPILER_FLAG(-fstrict-aliasing HAVE_STRICT_ALIASING)
IF("${HAVE_STRICT_ALIASING}")
ADD_DEFINITIONS(-fno-strict-aliasing)
ENDIF()
# Set visibility options if available
IF(NOT WIN32)
CHECK_C_SOURCE_COMPILES("int foo() __attribute__((destructor));
@@ -149,7 +144,7 @@ IF(DLOPEN)
ENDIF()
# Check if we have Windows headers
CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H)
CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H -D_WIN32_WINNT=0x0500)
IF(NOT HAVE_WINDOWS_H)
CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
IF(NOT HAVE_GETTIMEOFDAY)
@@ -167,6 +162,9 @@ IF(NOT HAVE_WINDOWS_H)
MESSAGE(FATAL_ERROR "PThreads is required for non-Windows builds!")
ENDIF()
# Some systems need pthread_np.h to get recursive mutexes
CHECK_INCLUDE_FILES("pthread.h;pthread_np.h" HAVE_PTHREAD_NP_H)
# _GNU_SOURCE is needed on some systems for extra attributes, and
# _REENTRANT is needed for libc thread-safety
ADD_DEFINITIONS(-D_GNU_SOURCE=1 -D_REENTRANT)
@@ -180,7 +178,8 @@ ENDIF()
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
IF(NOT HAVE_STDINT_H)
IF(HAVE_WINDOWS_H)
CHECK_C_SOURCE_COMPILES("\#include <windows.h>
CHECK_C_SOURCE_COMPILES("\#define _WIN32_WINNT 0x0500
\#include <windows.h>
__int64 foo;
int main() {return 0;}" HAVE___INT64)
ENDIF()
@@ -247,14 +246,6 @@ ENDIF()
# Check DSound/MMSystem backend
IF(HAVE_WINDOWS_H)
SET(CMAKE_REQUIRED_LIBRARIES ole32)
CHECK_C_SOURCE_COMPILES("int main() {return 0;}" HAVE_LIBOLE32)
SET(CMAKE_REQUIRED_LIBRARIES "")
# CHECK_LIBRARY_EXISTS(ole32 CoInitialize "" HAVE_LIBOLE32)
IF(HAVE_LIBOLE32)
SET(EXTRA_LIBS ole32 ${EXTRA_LIBS})
ENDIF()
IF(DSOUND)
CHECK_INCLUDE_FILE(dsound.h HAVE_DSOUND_H)
IF(HAVE_DSOUND_H)
@@ -262,14 +253,17 @@ IF(HAVE_WINDOWS_H)
SET(ALC_OBJS ${ALC_OBJS} Alc/dsound.c)
SET(BACKENDS "${BACKENDS} DirectSound,")
CHECK_LIBRARY_EXISTS(dxguid IID_IDirectSound "" HAVE_LIBDXGUID)
IF(HAVE_LIBDXGUID)
SET(EXTRA_LIBS dxguid ${EXTRA_LIBS})
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})
ENDIF()
ENDIF()
ENDIF()
IF(WINMM)
CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H)
CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0500)
IF(HAVE_MMSYSTEM_H)
SET(HAVE_WINMM 1)
SET(ALC_OBJS ${ALC_OBJS} Alc/winmm.c)
@@ -320,9 +314,20 @@ INSTALL(TARGETS ${LIBNAME}
)
INSTALL(FILES include/AL/al.h
include/AL/alc.h
include/AL/alext.h
DESTINATION include/AL
)
IF(EXAMPLES)
ADD_EXECUTABLE(openal-info examples/openal-info.c)
TARGET_LINK_LIBRARIES(openal-info ${LIBNAME})
INSTALL(TARGETS openal-info
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
ENDIF()
MESSAGE(STATUS "")
MESSAGE(STATUS "Building OpenAL with support for the following backends:")
MESSAGE(STATUS " ${BACKENDS}")
+23 -39
View File
@@ -8,12 +8,18 @@
#ifdef _WIN32
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
#else
#include <assert.h>
#include <pthread.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#endif
#include <sys/time.h>
#include <time.h>
#include <errno.h>
@@ -42,6 +48,10 @@ static inline void InitializeCriticalSection(CRITICAL_SECTION *cs)
assert(ret == 0);
ret = pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE);
#ifdef HAVE_PTHREAD_NP_H
if(ret != 0)
ret = pthread_mutexattr_setkind_np(&attrib, PTHREAD_MUTEX_RECURSIVE);
#endif
assert(ret == 0);
ret = pthread_mutex_init(cs, &attrib);
assert(ret == 0);
@@ -84,55 +94,32 @@ 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"
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
extern CRITICAL_SECTION _alMutex;
extern char _alDebug[256];
#define AL_PRINT(...) do { \
int _al_print_i; \
char *_al_print_fn = strrchr(__FILE__, '/'); \
if(!_al_print_fn) _al_print_fn = __FILE__; \
else _al_print_fn += 1; \
#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) \
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); \
_alDebug[sizeof(_alDebug)-1] = 0; \
fprintf(stderr, "%s", _alDebug); \
} while(0)
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#define AL_FORMAT_MONO_IMA4 0x1300
#define AL_FORMAT_STEREO_IMA4 0x1301
#define AL_FORMAT_QUAD8_LOKI 0x10004
#define AL_FORMAT_QUAD16_LOKI 0x10005
#define AL_FORMAT_51CHN8 0x120A
#define AL_FORMAT_51CHN16 0x120B
#define AL_FORMAT_51CHN32 0x120C
#define AL_FORMAT_61CHN8 0x120D
#define AL_FORMAT_61CHN16 0x120E
#define AL_FORMAT_61CHN32 0x120F
#define AL_FORMAT_71CHN8 0x1210
#define AL_FORMAT_71CHN16 0x1211
#define AL_FORMAT_71CHN32 0x1212
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206
#define AL_FORMAT_REAR8 0x1207
#define AL_FORMAT_REAR16 0x1208
#define AL_FORMAT_REAR32 0x1209
#define SWMIXER_OUTPUT_RATE 44100
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
@@ -159,13 +146,10 @@ void alc_wave_init(BackendFuncs *func_list);
struct ALCdevice_struct
{
ALboolean InUse;
ALboolean IsCaptureDevice;
ALuint Frequency;
ALuint UpdateFreq;
ALuint FrameSize;
ALuint Channels;
ALuint UpdateSize;
ALenum Format;
ALCchar *szDeviceName;
+2
View File
@@ -8,6 +8,8 @@
extern "C" {
#endif
extern ALboolean DuplicateStereo;
__inline ALuint aluBytesFromFormat(ALenum format);
__inline ALuint aluChannelsFromFormat(ALenum format);
ALvoid aluMixData(ALCcontext *context,ALvoid *buffer,ALsizei size,ALenum format);
+7 -3
View File
@@ -493,16 +493,20 @@ static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *ALEffectSlot,
alSetError(AL_OUT_OF_MEMORY);
return;
}
if(ALEffectSlot->ReverbBuffer)
memcpy(ptr, ALEffectSlot->ReverbBuffer, min(size, ALEffectSlot->ReverbLength)*sizeof(ALfloat));
ALEffectSlot->ReverbLength = size;
ALEffectSlot->ReverbPos = 0;
ALEffectSlot->ReverbPos %= size;
ALEffectSlot->ReverbReflectPos = (ALuint)(ALEffectSlot->ReverbLength -
((ALfloat)Context->Frequency *
effect->Reverb.ReflectionsDelay)) %
effect->Reverb.ReflectionsDelay) +
ALEffectSlot->ReverbPos) %
ALEffectSlot->ReverbLength;
ALEffectSlot->ReverbLatePos = (ALuint)(ALEffectSlot->ReverbLength -
((ALfloat)Context->Frequency *
(effect->Reverb.LateReverbDelay +
effect->Reverb.ReflectionsDelay))) %
effect->Reverb.ReflectionsDelay)) +
ALEffectSlot->ReverbPos) %
ALEffectSlot->ReverbLength;
ALEffectSlot->ReverbDecayGain = pow(1.0/32768.0, 1.0/(effect->Reverb.DecayTime/reverbwait));
}
+9
View File
@@ -4,6 +4,7 @@
# specified.
# The system-wide settings can be put in /etc/openal/alsoft.conf and user-
# specific override settings in ~/.alsoftrc.
# For Windows, these settings should go into %AppData%\alsoft.ini
# 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
@@ -44,6 +45,14 @@ 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
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
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.
+3
View File
@@ -46,4 +46,7 @@
/* Define if we have GCC's destructor attribute */
#cmakedefine HAVE_GCC_DESTRUCTOR
/* Define if we have pthread_np.h */
#cmakedefine HAVE_PTHREAD_NP_H
#endif
+171
View File
@@ -0,0 +1,171 @@
/*
* openal-info: Display information about ALC and AL.
*
* Idea based on glxinfo for OpenGL.
* Initial OpenAL version by Erik Hofman <erik@ehofman.com>.
* Further hacked by Sven Panne <sven.panne@aedion.de>.
* More work (clean up) by Chris Robinson <chris.kcat@gmail.com>.
*
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include "AL/alc.h"
#include "AL/al.h"
#include "AL/alext.h"
static const int indentation = 4;
static const int maxmimumWidth = 79;
static void printChar(int c, int *width)
{
putchar(c);
*width = ((c == '\n') ? 0 : ((*width) + 1));
}
static void indent(int *width)
{
int i;
for(i = 0; i < indentation; i++)
printChar(' ', width);
}
static void printExtensions(const char *header, char separator, const char *extensions)
{
int width = 0, start = 0, end = 0;
printf("%s:\n", header);
if(extensions == NULL || extensions[0] == '\0')
return;
indent(&width);
while (1)
{
if(extensions[end] == separator || extensions[end] == '\0')
{
if(width + end - start + 2 > maxmimumWidth)
{
printChar('\n', &width);
indent(&width);
}
while(start < end)
{
printChar(extensions[start], &width);
start++;
}
if(extensions[end] == '\0')
break;
start++;
end++;
if(extensions[end] == '\0')
break;
printChar(',', &width);
printChar(' ', &width);
}
end++;
}
printChar('\n', &width);
}
static void die(const char *kind, const char *description)
{
fprintf(stderr, "%s error %s occured\n", kind, description);
exit(EXIT_FAILURE);
}
static void checkForErrors(void)
{
{
ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
ALCenum error = alcGetError(device);
if(error != ALC_NO_ERROR)
die("ALC", (const char*)alcGetString(device, error));
}
{
ALenum error = alGetError();
if(error != AL_NO_ERROR)
die("AL", (const char*)alGetString(error));
}
}
static void printDevices(ALCenum which, const char *kind)
{
const char *s = alcGetString(NULL, which);
checkForErrors();
printf("Available %sdevices:\n", kind);
while(*s != '\0')
{
printf(" %s\n", s);
while(*s++ != '\0')
;
}
}
static void printALCInfo (void)
{
ALCint major, minor;
ALCdevice *device;
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
{
if(alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATE_ALL_EXT") == AL_TRUE)
printDevices(ALC_ALL_DEVICES_SPECIFIER, "playback ");
else
printDevices(ALC_DEVICE_SPECIFIER, "playback ");
printDevices(ALC_CAPTURE_DEVICE_SPECIFIER, "capture ");
}
else
printf("No device enumeration available\n");
device = alcGetContextsDevice(alcGetCurrentContext());
checkForErrors();
printf("Default device: %s\n",
alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER));
printf("Default capture device: %s\n",
alcGetString(device, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
checkForErrors();
printf("ALC version: %d.%d\n", (int)major, (int)minor);
printExtensions("ALC extensions", ' ',
alcGetString(device, ALC_EXTENSIONS));
checkForErrors();
}
static void printALInfo(void)
{
printf("OpenAL vendor string: %s\n", alGetString(AL_VENDOR));
printf("OpenAL renderer string: %s\n", alGetString(AL_RENDERER));
printf("OpenAL version string: %s\n", alGetString(AL_VERSION));
printExtensions("OpenAL extensions", ' ', alGetString(AL_EXTENSIONS));
checkForErrors();
}
int main()
{
ALCdevice *device = alcOpenDevice(NULL);
ALCcontext *context = alcCreateContext(device, NULL);
alcMakeContextCurrent(context);
checkForErrors();
printALCInfo();
printALInfo();
checkForErrors();
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
alcCloseDevice(device);
return EXIT_SUCCESS;
}
+69
View File
@@ -0,0 +1,69 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 2008 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
*/
#ifndef AL_ALEXT_H
#define AL_ALEXT_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AL_EXT_float32
#define AL_EXT_float32 1
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#endif
#ifndef AL_LOKI_quadriphonic
#define AL_LOKI_quadriphonic 1
#define AL_FORMAT_QUAD8_LOKI 0x10004
#define AL_FORMAT_QUAD16_LOKI 0x10005
#endif
#ifndef AL_EXT_MCFORMATS
#define AL_EXT_MCFORMATS 1
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206
#define AL_FORMAT_REAR8 0x1207
#define AL_FORMAT_REAR16 0x1208
#define AL_FORMAT_REAR32 0x1209
#define AL_FORMAT_51CHN8 0x120A
#define AL_FORMAT_51CHN16 0x120B
#define AL_FORMAT_51CHN32 0x120C
#define AL_FORMAT_61CHN8 0x120D
#define AL_FORMAT_61CHN16 0x120E
#define AL_FORMAT_61CHN32 0x120F
#define AL_FORMAT_71CHN8 0x1210
#define AL_FORMAT_71CHN16 0x1211
#define AL_FORMAT_71CHN32 0x1212
#endif
#ifndef AL_EXT_IMA4
#define AL_EXT_IMA4 1
#define AL_FORMAT_MONO_IMA4 0x1300
#define AL_FORMAT_STEREO_IMA4 0x1301
#endif
#ifdef __cplusplus
}
#endif
#endif