Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e963782b8c | |||
| 86c01aa62c | |||
| 15783d25e7 | |||
| 3243f69f21 | |||
| 10a87f510c | |||
| ca6feeda29 | |||
| cecf778de3 | |||
| fe79ab351a | |||
| dc0a3a6653 | |||
| fed346c285 | |||
| cad9b367a5 | |||
| 6e86146a25 | |||
| 49d9695ad9 | |||
| e15bc6b9ba | |||
| 28093a6dcb | |||
| 2af5498804 | |||
| 2b42d7fdb8 |
@@ -1248,6 +1248,8 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
|
||||
|
||||
ALCvoid ReleaseALC(ALCvoid)
|
||||
{
|
||||
InitAL();
|
||||
|
||||
#ifdef _DEBUG
|
||||
if(g_ulContextCount > 0)
|
||||
AL_PRINT("exit() %u device(s) and %u context(s) NOT deleted\n", g_ulDeviceCount, g_ulContextCount);
|
||||
|
||||
@@ -275,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));
|
||||
@@ -359,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)
|
||||
@@ -390,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;
|
||||
@@ -415,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;
|
||||
@@ -436,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;
|
||||
@@ -468,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))
|
||||
{
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct {
|
||||
ALuint (*func)(ALvoid*);
|
||||
ALvoid *ptr;
|
||||
|
||||
+5
-3
@@ -595,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);
|
||||
}
|
||||
|
||||
@@ -856,6 +857,7 @@ next_card:
|
||||
}
|
||||
|
||||
allCaptureDevNameMap[0].name = AppendCaptureDeviceList("ALSA Capture on default");
|
||||
idx = 1;
|
||||
|
||||
while (card >= 0) {
|
||||
sprintf(name, "hw:%d", card);
|
||||
@@ -889,9 +891,9 @@ next_card:
|
||||
dname = psnd_pcm_info_get_name(pcminfo);
|
||||
snprintf(name, sizeof(name), "ALSA Capture on %s [%s]",
|
||||
cname, dname);
|
||||
allDevNameMap[idx].name = AppendCaptureDeviceList(name);
|
||||
allDevNameMap[idx].card = card;
|
||||
allDevNameMap[idx].dev = dev;
|
||||
allCaptureDevNameMap[idx].name = AppendCaptureDeviceList(name);
|
||||
allCaptureDevNameMap[idx].card = card;
|
||||
allCaptureDevNameMap[idx].dev = dev;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-5
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#define INITGUID
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@@ -171,7 +172,25 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
|
||||
{
|
||||
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))
|
||||
{
|
||||
speakers = DSSPEAKER_CONFIG(speakers);
|
||||
@@ -275,10 +294,13 @@ static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceNam
|
||||
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))
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
+22
-13
@@ -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 "3")
|
||||
SET(LIB_BUILD_VERSION "253")
|
||||
SET(LIB_MINOR_VERSION "4")
|
||||
SET(LIB_BUILD_VERSION "270")
|
||||
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()
|
||||
@@ -264,7 +263,7 @@ IF(HAVE_WINDOWS_H)
|
||||
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)
|
||||
@@ -319,6 +318,16 @@ INSTALL(FILES include/AL/al.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}")
|
||||
|
||||
@@ -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);
|
||||
@@ -97,16 +107,16 @@ 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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user