Commit d0e93bb8 authored by Unicorn369's avatar Unicorn369 Committed by fallenstardust

openal-soft 1.19.1

parent a5fab90b
......@@ -7,24 +7,25 @@ LOCAL_MODULE := openal
LOCAL_C_INCLUDES := $(LOCAL_PATH)/android \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/src/Alc \
$(LOCAL_PATH)/src/common \
$(LOCAL_PATH)/src/OpenAL32 \
$(LOCAL_PATH)/src/OpenAL32/Include
LOCAL_SRC_FILES := \
src/Alc/ALc.c \
src/Alc/alcConfig.c \
src/Alc/alcRing.c \
src/Alc/ALu.c \
src/Alc/ambdec.c \
src/Alc/bformatdec.c \
src/Alc/alconfig.c \
src/Alc/bs2b.c \
src/Alc/bsinc.c \
src/Alc/converter.c \
src/Alc/mastering.c \
src/Alc/ringbuffer.c \
src/Alc/helpers.c \
src/Alc/hrtf.c \
src/Alc/mixer.c \
src/Alc/mixer_c.c \
src/Alc/panning.c \
src/Alc/uhjfilter.c \
src/Alc/ambdec.c \
src/Alc/bformatdec.c \
src/Alc/panning.c \
src/Alc/mixvoice.c \
\
src/Alc/effects/autowah.c \
src/Alc/effects/chorus.c \
......@@ -33,9 +34,10 @@ LOCAL_SRC_FILES := \
src/Alc/effects/distortion.c \
src/Alc/effects/echo.c \
src/Alc/effects/equalizer.c \
src/Alc/effects/flanger.c \
src/Alc/effects/fshifter.c \
src/Alc/effects/modulator.c \
src/Alc/effects/null.c \
src/Alc/effects/pshifter.c \
src/Alc/effects/reverb.c \
\
src/Alc/backends/base.c \
......@@ -44,6 +46,12 @@ LOCAL_SRC_FILES := \
src/Alc/backends/opensl.c \
src/Alc/backends/wave.c \
\
src/Alc/filters/filter.c \
src/Alc/filters/nfc.c \
src/Alc/filters/splitter.c \
\
src/Alc/mixer/mixer_c.c \
\
src/OpenAL32/alAuxEffectSlot.c \
src/OpenAL32/alBuffer.c \
src/OpenAL32/alEffect.c \
......@@ -53,16 +61,27 @@ LOCAL_SRC_FILES := \
src/OpenAL32/alListener.c \
src/OpenAL32/alSource.c \
src/OpenAL32/alState.c \
src/OpenAL32/alThunk.c \
src/OpenAL32/event.c \
src/OpenAL32/sample_cvt.c \
\
src/common/alcomplex.c \
src/common/almalloc.c \
src/common/alhelpers.c \
src/common/atomic.c \
src/common/rwlock.c \
src/common/threads.c \
src/common/uintmap.c
src/common/uintmap.c \
LOCAL_CFLAGS := -DAL_BUILD_LIBRARY -DAL_ALEXT_PROTOTYPES
ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
LOCAL_ARM_NEON := true
LOCAL_CFLAGS += -DHAVE_NEON
LOCAL_SRC_FILES += src/Alc/mixer/mixer_neon.c
endif
ifeq ($(TARGET_ARCH_ABI),x86)
LOCAL_CFLAGS += -DHAVE_SSE -DHAVE_SSE2 -DHAVE_SSE3 -DHAVE_SSE4_1 -DHAVE_CPUID_H -DHAVE_GCC_GET_CPUID
LOCAL_SRC_FILES += src/Alc/mixer/mixer_sse.c src/Alc/mixer/mixer_sse2.c src/Alc/mixer/mixer_sse3.c src/Alc/mixer/mixer_sse41.c
endif
include $(BUILD_STATIC_LIBRARY)
#ifndef ALHELPERS_H
#define ALHELPERS_H
#include "AL/alc.h"
#include "AL/al.h"
#include "AL/alext.h"
#include "threads.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Some helper functions to get the name from the channel and type enums. */
const char *ChannelsName(ALenum chans);
const char *TypeName(ALenum type);
/* Helpers to convert frame counts and byte lengths. */
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type);
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type);
/* Retrieves a compatible buffer format given the channel configuration and
* sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
* provided, it will be called to find the closest-matching format from
* AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
* found. */
ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT);
/* Loads samples into a buffer using the standard alBufferData call, but with a
* LPALBUFFERSAMPLESSOFT-compatible prototype. Assumes internalformat is valid
* for alBufferData, and that channels and type match it. */
void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
ALenum internalformat, ALsizei samples,
ALenum channels, ALenum type,
const ALvoid *data);
/* Easy device init/deinit functions. InitAL returns 0 on success. */
int InitAL(void);
void CloseAL(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ALHELPERS_H */
#ifndef CONFIG_H
#define CONFIG_H
/* Define to the library version */
#define ALSOFT_VERSION "1.13"
/* API declaration export attribute */
#define AL_API __attribute__((visibility("protected")))
#define ALC_API __attribute__((visibility("protected")))
/* Define any available alignment declaration */
#define ALIGN(x) __attribute__((aligned(x)))
/* Define if we have the Android backend */
#define HAVE_ANDROID 1
/* Define a built-in call indicating an aligned data pointer */
#define ASSUME_ALIGNED(x, y) __builtin_assume_aligned(x, y)
/* Define if HRTF data is embedded in the library */
//#define ALSOFT_EMBED_HRTF_DATA
/* Define if we have the sysconf function */
#define HAVE_SYSCONF
/* Define if we have the C11 aligned_alloc function */
/* #undef HAVE_ALIGNED_ALLOC */
/* Define if we have the posix_memalign function */
/* #undef HAVE_POSIX_MEMALIGN */
/* Define if we have the _aligned_malloc function */
/* #undef HAVE__ALIGNED_MALLOC */
#define HAVE_DIRENT_H 1
/* Define if we have the proc_pidpath function */
/* #undef HAVE_PROC_PIDPATH */
/* Define if we have the getopt function */
#define HAVE_GETOPT
/* Define if we have SSE CPU extensions */
/* #undef HAVE_SSE */
/* #undef HAVE_SSE2 */
/* #undef HAVE_SSE3 */
/* #undef HAVE_SSE4_1 */
/* Define if we have ARM Neon CPU extensions */
//#define HAVE_NEON
/* Define if we have the ALSA backend */
/* #cmakedefine HAVE_ALSA */
/* #undef HAVE_ALSA */
/* Define if we have the OSS backend */
/* #cmakedefine HAVE_OSS */
/* #undef HAVE_OSS */
/* Define if we have the Solaris backend */
/* #cmakedefine HAVE_SOLARIS */
/* #undef HAVE_SOLARIS */
/* Define if we have the SndIO backend */
/* #cmakedefine HAVE_SNDIO */
/* #undef HAVE_SNDIO */
/* Define if we have the MMDevApi backend */
/* #cmakedefine HAVE_MMDEVAPI */
/* Define if we have the QSA backend */
/* #undef HAVE_QSA */
/* Define if we have the WASAPI backend */
/* #undef HAVE_WASAPI */
/* Define if we have the DSound backend */
/* #cmakedefine HAVE_DSOUND */
/* #undef HAVE_DSOUND */
/* Define if we have the Windows Multimedia backend */
/* #cmakedefine HAVE_WINMM */
/* #undef HAVE_WINMM */
/* Define if we have the PortAudio backend */
/* #cmakedefine HAVE_PORTAUDIO */
/* #undef HAVE_PORTAUDIO */
/* Define if we have the PulseAudio backend */
/* #cmakedefine HAVE_PULSEAUDIO */
/* #undef HAVE_PULSEAUDIO */
/* Define if we have the JACK backend */
/* #undef HAVE_JACK */
/* Define if we have the CoreAudio backend */
/* #cmakedefine HAVE_COREAUDIO */
/* #undef HAVE_COREAUDIO */
/* Define if we have the OpenSL backend */
/* #cmakedefine HAVE_OPENSL */ /* THIS BACKEND WORKS ON >=2.3 Android!! */
#define HAVE_OPENSL
/* Define if we have the Wave Writer backend */
/* #cmakedefine HAVE_WAVE */
#define HAVE_WAVE
/* Define if we have dlfcn.h */
#define HAVE_DLFCN_H 1
/* Define if we have the SDL2 backend */
/* #undef HAVE_SDL2 */
/* Define if we have the stat function */
#define HAVE_STAT 1
/* Define if we have the powf function */
#define HAVE_POWF 1
/* Define if we have the sqrtf function */
#define HAVE_SQRTF 1
/* Define if we have the cosf function */
#define HAVE_COSF 1
/* Define if we have the sinf function */
#define HAVE_SINF 1
/* Define if we have the acosf function */
#define HAVE_ACOSF 1
#define HAVE_STAT
/* Define if we have the asinf function */
#define HAVE_ASINF 1
/* Define if we have the lrintf function */
#define HAVE_LRINTF
/* Define if we have the atanf function */
#define HAVE_ATANF 1
/* Define if we have the modff function */
#define HAVE_MODFF
/* Define if we have the atan2f function */
#define HAVE_ATAN2F 1
/* Define if we have the log2f function */
/* #undef HAVE_LOG2F */
/* Define if we have the fabsf function */
#define HAVE_FABSF 1
/* Define if we have the cbrtf function */
#define HAVE_CBRTF
/* Define if we have the log10f function */
#define HAVE_LOG10F 1
/* Define if we have the floorf function */
#define HAVE_FLOORF 1
/* Define if we have the copysignf function */
#define HAVE_COPYSIGNF
/* Define if we have the strtof function */
#define HAVE_STRTOF 1
/* #undef HAVE_STRTOF */
/* Define if we have stdint.h */
#define HAVE_STDINT_H 1
/* Define if we have the strnlen function */
#define HAVE_STRNLEN
/* Define if we have the __int64 type */
/* #cmakedefine HAVE___INT64 */
/* #undef HAVE___INT64 */
/* Define to the size of a long int type */
#define SIZEOF_LONG 4
......@@ -101,49 +116,110 @@
/* Define to the size of a long long int type */
#define SIZEOF_LONG_LONG 8
/* Define if we have C99 _Bool support */
#define HAVE_C99_BOOL
/* Define if we have C11 _Static_assert support */
#define HAVE_C11_STATIC_ASSERT
/* Define if we have C11 _Alignas support */
#define HAVE_C11_ALIGNAS
/* Define if we have C11 _Atomic support */
/* #undef HAVE_C11_ATOMIC */
/* Define if we have GCC's destructor attribute */
#define HAVE_GCC_DESTRUCTOR 1
#define HAVE_GCC_DESTRUCTOR
/* Define if we have GCC's format attribute */
#define HAVE_GCC_FORMAT 1
#define HAVE_GCC_FORMAT
/* Define if we have stdint.h */
#define HAVE_STDINT_H
/* Define if we have stdbool.h */
#define HAVE_STDBOOL_H
/* Define if we have stdalign.h */
#define HAVE_STDALIGN_H
/* Define if we have windows.h */
/* #undef HAVE_WINDOWS_H */
/* Define if we have dlfcn.h */
#define HAVE_DLFCN_H
/* Define if we have pthread_np.h */
/* #cmakedefine HAVE_PTHREAD_NP_H */
/* #undef HAVE_PTHREAD_NP_H */
/* Define if we have arm_neon.h */
/* #cmakedefine HAVE_ARM_NEON_H */
/* Define if we have malloc.h */
#define HAVE_MALLOC_H
/* Define if we have guiddef.h */
/* #cmakedefine HAVE_GUIDDEF_H */
/* Define if we have dirent.h */
#define HAVE_DIRENT_H
/* Define if we have strings.h */
#define HAVE_STRINGS_H
/* Define if we have cpuid.h */
/* #undef HAVE_CPUID_H */
/* Define if we have intrin.h */
/* #undef HAVE_INTRIN_H */
/* Define if we have sys/sysconf.h */
#define HAVE_SYS_SYSCONF_H
/* Define if we have guiddef.h */
/* #cmakedefine HAVE_INITGUID_H */
/* #undef HAVE_GUIDDEF_H */
/* Define if we have initguid.h */
/* #undef HAVE_INITGUID_H */
/* Define if we have ieeefp.h */
/* #cmakedefine HAVE_IEEEFP_H */
/* #undef HAVE_IEEEFP_H */
/* Define if we have float.h */
/* #cmakedefine HAVE_FLOAT_H */
/* Define if we have fpu_control.h */
/* #cmakedefine HAVE_FPU_CONTROL_H */
#define HAVE_FLOAT_H
/* Define if we have fenv.h */
#define HAVE_FENV_H 1
#define HAVE_FENV_H
/* Define if we have GCC's __get_cpuid() */
/* #undef HAVE_GCC_GET_CPUID */
/* Define if we have the __cpuid() intrinsic */
/* #undef HAVE_CPUID_INTRINSIC */
/* Define if we have fesetround() */
/* #cmakedefine HAVE_FESETROUND */
/* Define if we have the _BitScanForward64() intrinsic */
/* #undef HAVE_BITSCANFORWARD64_INTRINSIC */
/* Define if we have the _BitScanForward() intrinsic */
/* #undef HAVE_BITSCANFORWARD_INTRINSIC */
/* Define if we have _controlfp() */
/* #cmakedefine HAVE__CONTROLFP */
/* #undef HAVE__CONTROLFP */
/* Define if we have __control87_2() */
/* #undef HAVE___CONTROL87_2 */
/* Define if we have pthread_setschedparam() */
#define HAVE_PTHREAD_SETSCHEDPARAM 1
#define HAVE_PTHREAD_SETSCHEDPARAM
/* Define if we have pthread_setname_np() */
#define HAVE_PTHREAD_SETNAME_NP
/* Define if pthread_setname_np() only accepts one parameter */
/* #undef PTHREAD_SETNAME_NP_ONE_PARAM */
/* Define if pthread_setname_np() accepts three parameters */
/* #undef PTHREAD_SETNAME_NP_THREE_PARAMS */
/* Define if we have the restrict keyword */
/* #cmakedefine HAVE_RESTRICT 1 */
/* Define if we have pthread_set_name_np() */
/* #undef HAVE_PTHREAD_SET_NAME_NP */
/* Define if we have the __restrict keyword */
#define HAVE___RESTRICT 1
/* Define if we have pthread_mutexattr_setkind_np() */
/* #undef HAVE_PTHREAD_MUTEXATTR_SETKIND_NP */
#endif
/* Define if we have pthread_mutex_timedlock() */
/* #undef HAVE_PTHREAD_MUTEX_TIMEDLOCK */
#ifndef AL_MATH_DEFS_H
#define AL_MATH_DEFS_H
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#define F_PI (3.14159265358979323846f)
#define F_PI_2 (1.57079632679489661923f)
#define F_TAU (6.28318530717958647692f)
#ifndef FLT_EPSILON
#define FLT_EPSILON (1.19209290e-07f)
#endif
#define DEG2RAD(x) ((ALfloat)(x) * (F_PI/180.0f))
#define RAD2DEG(x) ((ALfloat)(x) * (180.0f/F_PI))
#endif /* AL_MATH_DEFS_H */
/* Define to the library version */
#define ALSOFT_VERSION "1.19.1"
/* Define the branch being built */
#define ALSOFT_GIT_BRANCH "UNKNOWN"
/* Define the hash of the head commit */
#define ALSOFT_GIT_COMMIT_HASH "unknown"
......@@ -21,16 +21,6 @@ extern "C" {
#define AL_APIENTRY
#endif
#ifdef ANDROID
#include <android/log.h>
#define LOG_TAG "OPENAL"
#ifndef ALOG
#define ALOG(...) __android_log_print(ANDROID_LOG_INFO,"OpenAL",__VA_ARGS__)
#endif
#else
#define ALOG printf
#endif
/** Deprecated macro. */
#define OPENAL
......
......@@ -97,6 +97,31 @@ extern "C" {
#ifndef AL_EXT_MCFORMATS
#define AL_EXT_MCFORMATS 1
/* Provides support for surround sound buffer formats with 8, 16, and 32-bit
* samples.
*
* QUAD8: Unsigned 8-bit, Quadraphonic (Front Left, Front Right, Rear Left,
* Rear Right).
* QUAD16: Signed 16-bit, Quadraphonic.
* QUAD32: 32-bit float, Quadraphonic.
* REAR8: Unsigned 8-bit, Rear Stereo (Rear Left, Rear Right).
* REAR16: Signed 16-bit, Rear Stereo.
* REAR32: 32-bit float, Rear Stereo.
* 51CHN8: Unsigned 8-bit, 5.1 Surround (Front Left, Front Right, Front Center,
* LFE, Side Left, Side Right). Note that some audio systems may label
* 5.1's Side channels as Rear or Surround; they are equivalent for the
* purposes of this extension.
* 51CHN16: Signed 16-bit, 5.1 Surround.
* 51CHN32: 32-bit float, 5.1 Surround.
* 61CHN8: Unsigned 8-bit, 6.1 Surround (Front Left, Front Right, Front Center,
* LFE, Rear Center, Side Left, Side Right).
* 61CHN16: Signed 16-bit, 6.1 Surround.
* 61CHN32: 32-bit float, 6.1 Surround.
* 71CHN8: Unsigned 8-bit, 7.1 Surround (Front Left, Front Right, Front Center,
* LFE, Rear Left, Rear Right, Side Left, Side Right).
* 71CHN16: Signed 16-bit, 7.1 Surround.
* 71CHN32: 32-bit float, 7.1 Surround.
*/
#define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206
......@@ -395,6 +420,16 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device);
#ifndef AL_EXT_BFORMAT
#define AL_EXT_BFORMAT 1
/* Provides support for B-Format ambisonic buffers (first-order, FuMa scaling
* and layout).
*
* BFORMAT2D_8: Unsigned 8-bit, 3-channel non-periphonic (WXY).
* BFORMAT2D_16: Signed 16-bit, 3-channel non-periphonic (WXY).
* BFORMAT2D_FLOAT32: 32-bit float, 3-channel non-periphonic (WXY).
* BFORMAT3D_8: Unsigned 8-bit, 4-channel periphonic (WXYZ).
* BFORMAT3D_16: Signed 16-bit, 4-channel periphonic (WXYZ).
* BFORMAT3D_FLOAT32: 32-bit float, 4-channel periphonic (WXYZ).
*/
#define AL_FORMAT_BFORMAT2D_8 0x20021
#define AL_FORMAT_BFORMAT2D_16 0x20022
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
......@@ -431,6 +466,49 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi
#endif
#endif
#ifndef AL_SOFT_gain_clamp_ex
#define AL_SOFT_gain_clamp_ex 1
#define AL_GAIN_LIMIT_SOFT 0x200E
#endif
#ifndef AL_SOFT_source_resampler
#define AL_SOFT_source_resampler
#define AL_NUM_RESAMPLERS_SOFT 0x1210
#define AL_DEFAULT_RESAMPLER_SOFT 0x1211
#define AL_SOURCE_RESAMPLER_SOFT 0x1212
#define AL_RESAMPLER_NAME_SOFT 0x1213
typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index);
#ifdef AL_ALEXT_PROTOTYPES
AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
#endif
#endif
#ifndef AL_SOFT_source_spatialize
#define AL_SOFT_source_spatialize
#define AL_SOURCE_SPATIALIZE_SOFT 0x1214
#define AL_AUTO_SOFT 0x0002
#endif
#ifndef ALC_SOFT_output_limiter
#define ALC_SOFT_output_limiter
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
#endif
#ifndef ALC_SOFT_device_clock
#define ALC_SOFT_device_clock 1
typedef int64_t ALCint64SOFT;
typedef uint64_t ALCuint64SOFT;
#define ALC_DEVICE_CLOCK_SOFT 0x1600
#define ALC_DEVICE_LATENCY_SOFT 0x1601
#define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602
#define AL_SAMPLE_OFFSET_CLOCK_SOFT 0x1202
#define AL_SEC_OFFSET_CLOCK_SOFT 0x1203
typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
#endif
#endif
#ifdef __cplusplus
}
#endif
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* 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;
ALfp *SampleBuffer;
ALuint BufferLength;
// The echo is two tap. The delay is the number of samples from before the
// current offset
struct {
ALuint delay;
} Tap[2];
ALuint Offset;
// The LR gains for the first tap. The second tap uses the reverse
ALfp GainL;
ALfp GainR;
ALfp FeedGain;
ALfp Gain[MAXCHANNELS];
FILTER iirFilter;
ALfp history[2];
} ALechoState;
static ALvoid EchoDestroy(ALeffectState *effect)
{
ALechoState *state = (ALechoState*)effect;
if(state)
{
free(state->SampleBuffer);
state->SampleBuffer = NULL;
free(state);
}
}
static ALboolean EchoDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
{
ALechoState *state = (ALechoState*)effect;
ALuint maxlen, i;
// Use the next power of 2 for the buffer length, so the tap offsets can be
// wrapped using a mask instead of a modulo
maxlen = (ALuint)(AL_ECHO_MAX_DELAY * Device->Frequency) + 1;
maxlen += (ALuint)(AL_ECHO_MAX_LRDELAY * Device->Frequency) + 1;
maxlen = NextPowerOf2(maxlen);
if(maxlen != state->BufferLength)
{
void *temp;
temp = realloc(state->SampleBuffer, maxlen * sizeof(ALfp));
if(!temp)
return AL_FALSE;
state->SampleBuffer = temp;
state->BufferLength = maxlen;
}
for(i = 0;i < state->BufferLength;i++)
state->SampleBuffer[i] = int2ALfp(0);
for(i = 0;i < MAXCHANNELS;i++)
state->Gain[i] = int2ALfp(0);
for(i = 0;i < Device->NumChan;i++)
{
Channel chan = Device->Speaker2Chan[i];
state->Gain[chan] = int2ALfp(1);
}
return AL_TRUE;
}
static ALvoid EchoUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect)
{
ALechoState *state = (ALechoState*)effect;
ALuint frequency = Context->Device->Frequency;
ALfp lrpan, cw, a, g;
state->Tap[0].delay = (ALuint)ALfp2int((ALfpMult(Effect->Echo.Delay, int2ALfp(frequency)) + int2ALfp(1)));
state->Tap[1].delay = (ALuint)ALfp2int(ALfpMult(Effect->Echo.LRDelay, int2ALfp(frequency)));
state->Tap[1].delay += state->Tap[0].delay;
lrpan = (ALfpMult(Effect->Echo.Spread, float2ALfp(0.5f)) + float2ALfp(0.5f));
state->GainL = aluSqrt( lrpan);
state->GainR = aluSqrt((int2ALfp(1)-lrpan));
state->FeedGain = Effect->Echo.Feedback;
cw = __cos(ALfpDiv(float2ALfp(2.0*M_PI * LOWPASSFREQCUTOFF), int2ALfp(frequency)));
g = (int2ALfp(1) - Effect->Echo.Damping);
a = int2ALfp(0);
if(g < float2ALfp(0.9999f)) /* 1-epsilon */ {
// a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) / (1 - g);
a = ALfpDiv((int2ALfp(1) - ALfpMult(g,cw) - aluSqrt((ALfpMult(ALfpMult(int2ALfp(2),g),(int2ALfp(1)-cw)) -
ALfpMult(ALfpMult(g,g),(int2ALfp(1) - ALfpMult(cw,cw)))))),
(int2ALfp(1) - g));
}
state->iirFilter.coeff = a;
}
static ALvoid EchoProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfp *SamplesIn, ALfp (*SamplesOut)[MAXCHANNELS])
{
ALechoState *state = (ALechoState*)effect;
const ALuint mask = state->BufferLength-1;
const ALuint tap1 = state->Tap[0].delay;
const ALuint tap2 = state->Tap[1].delay;
ALuint offset = state->Offset;
const ALfp gain = Slot->Gain;
ALfp samp[2], smp;
ALuint i;
for(i = 0;i < SamplesToDo;i++,offset++)
{
// Sample first tap
smp = state->SampleBuffer[(offset-tap1) & mask];
samp[0] = ALfpMult(smp, state->GainL);
samp[1] = ALfpMult(smp, state->GainR);
// Sample second tap. Reverse LR panning
smp = state->SampleBuffer[(offset-tap2) & mask];
samp[0] += ALfpMult(smp, state->GainR);
samp[1] += ALfpMult(smp, state->GainL);
// Apply damping and feedback gain to the second tap, and mix in the
// new sample
smp = lpFilter2P(&state->iirFilter, 0, (smp+SamplesIn[i]));
state->SampleBuffer[offset&mask] = ALfpMult(smp, state->FeedGain);
// Apply slot gain
samp[0] = ALfpMult(samp[0], gain);
samp[1] = ALfpMult(samp[1], gain);
SamplesOut[i][FRONT_LEFT] += ALfpMult(state->Gain[FRONT_LEFT], samp[0]);
SamplesOut[i][FRONT_RIGHT] += ALfpMult(state->Gain[FRONT_RIGHT], samp[1]);
#ifdef APPORTABLE_OPTIMIZED_OUT
SamplesOut[i][SIDE_LEFT] += ALfpMult(state->Gain[SIDE_LEFT], samp[0]);
SamplesOut[i][SIDE_RIGHT] += ALfpMult(state->Gain[SIDE_RIGHT], samp[1]);
SamplesOut[i][BACK_LEFT] += ALfpMult(state->Gain[BACK_LEFT], samp[0]);
SamplesOut[i][BACK_RIGHT] += ALfpMult(state->Gain[BACK_RIGHT], samp[1]);
#endif
}
state->Offset = offset;
}
ALeffectState *EchoCreate(void)
{
ALechoState *state;
state = malloc(sizeof(*state));
if(!state)
return NULL;
state->state.Destroy = EchoDestroy;
state->state.DeviceUpdate = EchoDeviceUpdate;
state->state.Update = EchoUpdate;
state->state.Process = EchoProcess;
state->BufferLength = 0;
state->SampleBuffer = NULL;
state->Tap[0].delay = 0;
state->Tap[1].delay = 0;
state->Offset = 0;
state->GainL = int2ALfp(0);
state->GainR = int2ALfp(0);
state->iirFilter.coeff = int2ALfp(0);
state->iirFilter.history[0] = int2ALfp(0);
state->iirFilter.history[1] = int2ALfp(0);
return &state->state;
}
/**
* 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 ALmodulatorState {
// Must be first in all effects!
ALeffectState state;
enum {
SINUSOID,
SAWTOOTH,
SQUARE
} Waveform;
ALuint index;
ALuint step;
ALfp Gain[MAXCHANNELS];
FILTER iirFilter;
ALfp history[1];
} ALmodulatorState;
#define WAVEFORM_FRACBITS 16
#define WAVEFORM_FRACMASK ((1<<WAVEFORM_FRACBITS)-1)
static __inline ALfp sin_func(ALuint index)
{
return __sin(ALdfpMult(ALdfpDiv(int2ALdfp(index),double2ALdfp(1<<WAVEFORM_FRACBITS)), double2ALdfp(M_PI * 2.0f)));
}
static __inline ALfp saw_func(ALuint index)
{
return (ALfpDiv(int2ALfp(index*2), int2ALfp(1<<WAVEFORM_FRACBITS)) - int2ALfp(1));
}
static __inline ALfp square_func(ALuint index)
{
return int2ALfp((float)((index>>(WAVEFORM_FRACBITS-1))&1) ? -1 : 1);
}
static __inline ALfp hpFilter1P(FILTER *iir, ALuint offset, ALfp input)
{
ALfp *history = &iir->history[offset];
ALfp a = iir->coeff;
ALfp output = input;
output = (output + ALfpMult((history[0]-output),a));
history[0] = output;
return (input - output);
}
static ALvoid ModulatorDestroy(ALeffectState *effect)
{
ALmodulatorState *state = (ALmodulatorState*)effect;
free(state);
}
static ALboolean ModulatorDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
{
ALmodulatorState *state = (ALmodulatorState*)effect;
ALuint index;
for(index = 0;index < MAXCHANNELS;index++)
state->Gain[index] = int2ALfp(0);
for(index = 0;index < Device->NumChan;index++)
{
Channel chan = Device->Speaker2Chan[index];
state->Gain[chan] = int2ALfp(1);
}
return AL_TRUE;
}
static ALvoid ModulatorUpdate(ALeffectState *effect, ALCcontext *Context, const ALeffect *Effect)
{
ALmodulatorState *state = (ALmodulatorState*)effect;
ALfp cw, a;
a = int2ALfp(0);
if(Effect->Modulator.Waveform == AL_RING_MODULATOR_SINUSOID)
state->Waveform = SINUSOID;
else if(Effect->Modulator.Waveform == AL_RING_MODULATOR_SAWTOOTH)
state->Waveform = SAWTOOTH;
else if(Effect->Modulator.Waveform == AL_RING_MODULATOR_SQUARE)
state->Waveform = SQUARE;
state->step = ALfp2int(ALfpDiv(ALfpMult(Effect->Modulator.Frequency,
int2ALfp(1<<WAVEFORM_FRACBITS)),
int2ALfp(Context->Device->Frequency)));
if(!state->step)
state->step = 1;
cw = __cos(ALfpDiv(ALfpMult(float2ALfp(2.0*M_PI),
Effect->Modulator.HighPassCutoff),
int2ALfp(Context->Device->Frequency)));
a = ((int2ALfp(2)-cw) -
aluSqrt((aluPow((int2ALfp(2)-cw), int2ALfp(2)) - int2ALfp(1))));
state->iirFilter.coeff = a;
}
static ALvoid ModulatorProcess(ALeffectState *effect, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfp *SamplesIn, ALfp (*SamplesOut)[MAXCHANNELS])
{
ALmodulatorState *state = (ALmodulatorState*)effect;
const ALfp gain = Slot->Gain;
const ALuint step = state->step;
ALuint index = state->index;
ALfp samp;
ALuint i;
switch(state->Waveform)
{
case SINUSOID:
for(i = 0;i < SamplesToDo;i++)
{
#ifdef APPORTABLE_OPTIMIZED_OUT
#define FILTER_OUT(func) do { \
samp = SamplesIn[i]; \
\
index += step; \
index &= WAVEFORM_FRACMASK; \
samp *= func(index); \
\
samp = hpFilter1P(&state->iirFilter, 0, samp); \
\
/* Apply slot gain */ \
samp *= gain; \
\
SamplesOut[i][FRONT_LEFT] += state->Gain[FRONT_LEFT] * samp; \
SamplesOut[i][FRONT_RIGHT] += state->Gain[FRONT_RIGHT] * samp; \
SamplesOut[i][FRONT_CENTER] += state->Gain[FRONT_CENTER] * samp; \
SamplesOut[i][SIDE_LEFT] += state->Gain[SIDE_LEFT] * samp; \
SamplesOut[i][SIDE_RIGHT] += state->Gain[SIDE_RIGHT] * samp; \
SamplesOut[i][BACK_LEFT] += state->Gain[BACK_LEFT] * samp; \
SamplesOut[i][BACK_RIGHT] += state->Gain[BACK_RIGHT] * samp; \
SamplesOut[i][BACK_CENTER] += state->Gain[BACK_CENTER] * samp; \
} while(0)
#else
//Apportable optimized version
#define FILTER_OUT(func) do { \
samp = SamplesIn[i]; \
\
index += step; \
index &= WAVEFORM_FRACMASK; \
samp = ALfpMult(samp, func(index)); \
\
samp = hpFilter1P(&state->iirFilter, 0, samp); \
\
/* Apply slot gain */ \
samp = ALfpMult(samp, gain); \
\
SamplesOut[i][FRONT_LEFT] += ALfpMult(state->Gain[FRONT_LEFT], samp); \
SamplesOut[i][FRONT_RIGHT] += ALfpMult(state->Gain[FRONT_RIGHT], samp); \
} while(0)
#endif
FILTER_OUT(sin_func);
}
break;
case SAWTOOTH:
for(i = 0;i < SamplesToDo;i++)
{
FILTER_OUT(saw_func);
}
break;
case SQUARE:
for(i = 0;i < SamplesToDo;i++)
{
FILTER_OUT(square_func);
#undef FILTER_OUT
}
break;
}
state->index = index;
}
ALeffectState *ModulatorCreate(void)
{
ALmodulatorState *state;
state = malloc(sizeof(*state));
if(!state)
return NULL;
state->state.Destroy = ModulatorDestroy;
state->state.DeviceUpdate = ModulatorDeviceUpdate;
state->state.Update = ModulatorUpdate;
state->state.Process = ModulatorProcess;
state->index = 0;
state->step = 1;
state->iirFilter.coeff = int2ALfp(0);
state->iirFilter.history[0] = int2ALfp(0);
return &state->state;
}
This diff is collapsed.
/**
* 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 "alMain.h"
#include "alThunk.h"
#ifdef _WIN32
typedef struct {
ALuint (*func)(ALvoid*);
ALvoid *ptr;
HANDLE thread;
} ThreadInfo;
static DWORD CALLBACK StarterFunc(void *ptr)
{
ThreadInfo *inf = (ThreadInfo*)ptr;
ALint ret;
ret = inf->func(inf->ptr);
ExitThread((DWORD)ret);
return (DWORD)ret;
}
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
{
DWORD dummy;
ThreadInfo *inf = malloc(sizeof(ThreadInfo));
if(!inf) return 0;
inf->func = func;
inf->ptr = ptr;
inf->thread = CreateThread(NULL, 0, StarterFunc, inf, 0, &dummy);
if(!inf->thread)
{
free(inf);
return NULL;
}
return inf;
}
ALuint StopThread(ALvoid *thread)
{
ThreadInfo *inf = thread;
DWORD ret = 0;
WaitForSingleObject(inf->thread, INFINITE);
GetExitCodeThread(inf->thread, &ret);
CloseHandle(inf->thread);
free(inf);
return (ALuint)ret;
}
#else
#include <pthread.h>
typedef struct {
ALuint (*func)(ALvoid*);
ALvoid *ptr;
ALuint ret;
pthread_t thread;
} ThreadInfo;
static void *StarterFunc(void *ptr)
{
ThreadInfo *inf = (ThreadInfo*)ptr;
inf->ret = inf->func(inf->ptr);
return NULL;
}
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
{
ThreadInfo *inf = malloc(sizeof(ThreadInfo));
if(!inf) return NULL;
inf->func = func;
inf->ptr = ptr;
if(pthread_create(&inf->thread, NULL, StarterFunc, inf) != 0)
{
free(inf);
return NULL;
}
return inf;
}
ALuint StopThread(ALvoid *thread)
{
ThreadInfo *inf = thread;
ALuint ret;
pthread_join(inf->thread, NULL);
ret = inf->ret;
free(inf);
return ret;
}
#endif
#ifndef ALCONFIG_H
#define ALCONFIG_H
void ReadALConfig(void);
void FreeALConfig(void);
int ConfigValueExists(const char *devName, const char *blockName, const char *keyName);
const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def);
int GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, int def);
int ConfigValueStr(const char *devName, const char *blockName, const char *keyName, const char **ret);
int ConfigValueInt(const char *devName, const char *blockName, const char *keyName, int *ret);
int ConfigValueUInt(const char *devName, const char *blockName, const char *keyName, unsigned int *ret);
int ConfigValueFloat(const char *devName, const char *blockName, const char *keyName, float *ret);
int ConfigValueBool(const char *devName, const char *blockName, const char *keyName, int *ret);
#endif /* ALCONFIG_H */
......@@ -6,44 +6,53 @@
#include "vector.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef char al_string_char_type;
TYPEDEF_VECTOR(al_string_char_type, al_string)
TYPEDEF_VECTOR(al_string, vector_al_string)
inline void al_string_deinit(al_string *str)
inline void alstr_reset(al_string *str)
{ VECTOR_DEINIT(*str); }
#define AL_STRING_INIT(_x) do { (_x) = (al_string)NULL; } while(0)
#define AL_STRING_INIT_STATIC() ((al_string)NULL)
#define AL_STRING_DEINIT(_x) al_string_deinit(&(_x))
#define AL_STRING_DEINIT(_x) alstr_reset(&(_x))
inline size_t al_string_length(const_al_string str)
inline size_t alstr_length(const_al_string str)
{ return VECTOR_SIZE(str); }
inline ALboolean al_string_empty(const_al_string str)
{ return al_string_length(str) == 0; }
inline ALboolean alstr_empty(const_al_string str)
{ return alstr_length(str) == 0; }
inline const al_string_char_type *al_string_get_cstr(const_al_string str)
inline const al_string_char_type *alstr_get_cstr(const_al_string str)
{ return str ? &VECTOR_FRONT(str) : ""; }
void al_string_clear(al_string *str);
void alstr_clear(al_string *str);
int al_string_cmp(const_al_string str1, const_al_string str2);
int al_string_cmp_cstr(const_al_string str1, const al_string_char_type *str2);
int alstr_cmp(const_al_string str1, const_al_string str2);
int alstr_cmp_cstr(const_al_string str1, const al_string_char_type *str2);
void al_string_copy(al_string *str, const_al_string from);
void al_string_copy_cstr(al_string *str, const al_string_char_type *from);
void al_string_copy_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to);
void alstr_copy(al_string *str, const_al_string from);
void alstr_copy_cstr(al_string *str, const al_string_char_type *from);
void alstr_copy_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to);
void al_string_append_char(al_string *str, const al_string_char_type c);
void al_string_append_cstr(al_string *str, const al_string_char_type *from);
void al_string_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to);
void alstr_append_char(al_string *str, const al_string_char_type c);
void alstr_append_cstr(al_string *str, const al_string_char_type *from);
void alstr_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to);
#ifdef _WIN32
#include <wchar.h>
/* Windows-only methods to deal with WideChar strings. */
void al_string_copy_wcstr(al_string *str, const wchar_t *from);
void al_string_append_wcstr(al_string *str, const wchar_t *from);
void al_string_append_wrange(al_string *str, const wchar_t *from, const wchar_t *to);
void alstr_copy_wcstr(al_string *str, const wchar_t *from);
void alstr_append_wcstr(al_string *str, const wchar_t *from);
void alstr_copy_wrange(al_string *str, const wchar_t *from, const wchar_t *to);
void alstr_append_wrange(al_string *str, const wchar_t *from, const wchar_t *to);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* ALSTRING_H */
......@@ -90,6 +90,15 @@ static char *my_strtok_r(char *str, const char *delim, char **saveptr)
return str;
}
static char *read_int(ALint *num, const char *line, int base)
{
char *end;
*num = strtol(line, &end, base);
if(end && *end != '\0')
end = lstrip(end);
return end;
}
static char *read_uint(ALuint *num, const char *line, int base)
{
char *end;
......@@ -131,7 +140,7 @@ char *read_clipped_line(FILE *f, char **buffer, size_t *maxlen)
static int load_ambdec_speakers(AmbDecConf *conf, FILE *f, char **buffer, size_t *maxlen, char **saveptr)
{
ALuint cur = 0;
ALsizei cur = 0;
while(cur < conf->NumSpeakers)
{
const char *cmd = my_strtok_r(NULL, " \t", saveptr);
......@@ -155,7 +164,7 @@ static int load_ambdec_speakers(AmbDecConf *conf, FILE *f, char **buffer, size_t
const char *conn = my_strtok_r(NULL, " \t", saveptr);
if(!name) WARN("Name not specified for speaker %u\n", cur+1);
else al_string_copy_cstr(&conf->Speakers[cur].Name, name);
else alstr_copy_cstr(&conf->Speakers[cur].Name, name);
if(!dist) WARN("Distance not specified for speaker %u\n", cur+1);
else read_float(&conf->Speakers[cur].Distance, dist);
if(!az) WARN("Azimuth not specified for speaker %u\n", cur+1);
......@@ -163,7 +172,7 @@ static int load_ambdec_speakers(AmbDecConf *conf, FILE *f, char **buffer, size_t
if(!elev) WARN("Elevation not specified for speaker %u\n", cur+1);
else read_float(&conf->Speakers[cur].Elevation, elev);
if(!conn) TRACE("Connection not specified for speaker %u\n", cur+1);
else al_string_copy_cstr(&conf->Speakers[cur].Connection, conn);
else alstr_copy_cstr(&conf->Speakers[cur].Connection, conn);
cur++;
}
......@@ -184,10 +193,10 @@ static int load_ambdec_speakers(AmbDecConf *conf, FILE *f, char **buffer, size_t
return 1;
}
static int load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS], ALuint maxrow, FILE *f, char **buffer, size_t *maxlen, char **saveptr)
static int load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS], ALsizei maxrow, FILE *f, char **buffer, size_t *maxlen, char **saveptr)
{
int gotgains = 0;
ALuint cur = 0;
ALsizei cur = 0;
while(cur < maxrow)
{
const char *cmd = my_strtok_r(NULL, " \t", saveptr);
......@@ -269,7 +278,7 @@ static int load_ambdec_matrix(ALfloat *gains, ALfloat (*matrix)[MAX_AMBI_COEFFS]
void ambdec_init(AmbDecConf *conf)
{
ALuint i;
ALsizei i;
memset(conf, 0, sizeof(*conf));
AL_STRING_INIT(conf->Description);
......@@ -282,13 +291,13 @@ void ambdec_init(AmbDecConf *conf)
void ambdec_deinit(AmbDecConf *conf)
{
ALuint i;
ALsizei i;
al_string_deinit(&conf->Description);
alstr_reset(&conf->Description);
for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
{
al_string_deinit(&conf->Speakers[i].Name);
al_string_deinit(&conf->Speakers[i].Connection);
alstr_reset(&conf->Speakers[i].Name);
alstr_reset(&conf->Speakers[i].Connection);
}
memset(conf, 0, sizeof(*conf));
}
......@@ -322,7 +331,7 @@ int ambdec_load(AmbDecConf *conf, const char *fname)
if(strcmp(command, "description") == 0)
{
char *value = my_strtok_r(NULL, "", &saveptr);
al_string_copy_cstr(&conf->Description, lstrip(value));
alstr_copy_cstr(&conf->Description, lstrip(value));
}
else if(strcmp(command, "version") == 0)
{
......@@ -370,7 +379,7 @@ int ambdec_load(AmbDecConf *conf, const char *fname)
else if(strcmp(dec, "speakers") == 0)
{
line = my_strtok_r(NULL, "", &saveptr);
line = read_uint(&conf->NumSpeakers, line, 10);
line = read_int(&conf->NumSpeakers, line, 10);
if(line && *line != '\0')
{
ERR("Extra junk after speakers: %s\n", line);
......
......@@ -17,7 +17,7 @@ typedef struct AmbDecConf {
ALuint ChanMask;
ALuint FreqBands; /* Must be 1 or 2 */
ALuint NumSpeakers;
ALsizei NumSpeakers;
enum AmbDecScaleType CoeffScale;
ALfloat XOverFreq;
......
This diff is collapsed.
......@@ -4,11 +4,15 @@
#include <stdlib.h>
#include "alMain.h"
#include "alu.h"
#include "backends/base.h"
extern inline ALuint64 GetDeviceClockTime(ALCdevice *device);
extern inline void ALCdevice_Lock(ALCdevice *device);
extern inline void ALCdevice_Unlock(ALCdevice *device);
extern inline ClockLatency GetClockLatency(ALCdevice *device);
/* Base ALCbackend method implementations. */
void ALCbackend_Construct(ALCbackend *self, ALCdevice *device)
......@@ -41,13 +45,22 @@ ALCuint ALCbackend_availableSamples(ALCbackend* UNUSED(self))
ClockLatency ALCbackend_getClockLatency(ALCbackend *self)
{
ALCdevice *device = self->mDevice;
ALuint refcount;
ClockLatency ret;
almtx_lock(&self->mMutex);
ret.ClockTime = GetDeviceClockTime(device);
// TODO: Perhaps should be NumUpdates-1 worth of UpdateSize?
ret.Latency = 0;
almtx_unlock(&self->mMutex);
do {
while(((refcount=ATOMIC_LOAD(&device->MixCount, almemory_order_acquire))&1))
althrd_yield();
ret.ClockTime = GetDeviceClockTime(device);
ATOMIC_THREAD_FENCE(almemory_order_acquire);
} while(refcount != ATOMIC_LOAD(&device->MixCount, almemory_order_relaxed));
/* NOTE: The device will generally have about all but one periods filled at
* any given time during playback. Without a more accurate measurement from
* the output, this is an okay approximation.
*/
ret.Latency = device->UpdateSize * DEVICE_CLOCK_RES / device->Frequency *
maxu(device->NumUpdates-1, 1);
return ret;
}
......@@ -69,157 +82,3 @@ void ALCbackend_unlock(ALCbackend *self)
void ALCbackendFactory_deinit(ALCbackendFactory* UNUSED(self))
{
}
/* Wrappers to use an old-style backend with the new interface. */
typedef struct PlaybackWrapper {
DERIVE_FROM_TYPE(ALCbackend);
const BackendFuncs *Funcs;
} PlaybackWrapper;
static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device, const BackendFuncs *funcs);
static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, Destruct)
static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name);
static void PlaybackWrapper_close(PlaybackWrapper *self);
static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self);
static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self);
static void PlaybackWrapper_stop(PlaybackWrapper *self);
static DECLARE_FORWARD2(PlaybackWrapper, ALCbackend, ALCenum, captureSamples, void*, ALCuint)
static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALCuint, availableSamples)
static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ClockLatency, getClockLatency)
static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, lock)
static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(PlaybackWrapper)
DEFINE_ALCBACKEND_VTABLE(PlaybackWrapper);
static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device, const BackendFuncs *funcs)
{
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(PlaybackWrapper, ALCbackend, self);
self->Funcs = funcs;
}
static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->OpenPlayback(device, name);
}
static void PlaybackWrapper_close(PlaybackWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
self->Funcs->ClosePlayback(device);
}
static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->ResetPlayback(device);
}
static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->StartPlayback(device);
}
static void PlaybackWrapper_stop(PlaybackWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
self->Funcs->StopPlayback(device);
}
typedef struct CaptureWrapper {
DERIVE_FROM_TYPE(ALCbackend);
const BackendFuncs *Funcs;
} CaptureWrapper;
static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device, const BackendFuncs *funcs);
static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, Destruct)
static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name);
static void CaptureWrapper_close(CaptureWrapper *self);
static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ALCboolean, reset)
static ALCboolean CaptureWrapper_start(CaptureWrapper *self);
static void CaptureWrapper_stop(CaptureWrapper *self);
static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples);
static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self);
static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ClockLatency, getClockLatency)
static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, lock)
static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, unlock)
DECLARE_DEFAULT_ALLOCATORS(CaptureWrapper)
DEFINE_ALCBACKEND_VTABLE(CaptureWrapper);
static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device, const BackendFuncs *funcs)
{
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(CaptureWrapper, ALCbackend, self);
self->Funcs = funcs;
}
static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->OpenCapture(device, name);
}
static void CaptureWrapper_close(CaptureWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
self->Funcs->CloseCapture(device);
}
static ALCboolean CaptureWrapper_start(CaptureWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
self->Funcs->StartCapture(device);
return ALC_TRUE;
}
static void CaptureWrapper_stop(CaptureWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
self->Funcs->StopCapture(device);
}
static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->CaptureSamples(device, buffer, samples);
}
static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
return self->Funcs->AvailableSamples(device);
}
ALCbackend *create_backend_wrapper(ALCdevice *device, const BackendFuncs *funcs, ALCbackend_Type type)
{
if(type == ALCbackend_Playback)
{
PlaybackWrapper *backend;
NEW_OBJ(backend, PlaybackWrapper)(device, funcs);
if(!backend) return NULL;
return STATIC_CAST(ALCbackend, backend);
}
if(type == ALCbackend_Capture)
{
CaptureWrapper *backend;
NEW_OBJ(backend, CaptureWrapper)(device, funcs);
if(!backend) return NULL;
return STATIC_CAST(ALCbackend, backend);
}
return NULL;
}
......@@ -3,8 +3,13 @@
#include "alMain.h"
#include "threads.h"
#include "alstring.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ClockLatency {
ALint64 ClockTime;
ALint64 Latency;
......@@ -43,7 +48,6 @@ struct ALCbackendVtable {
void (*const Destruct)(ALCbackend*);
ALCenum (*const open)(ALCbackend*, const ALCchar*);
void (*const close)(ALCbackend*);
ALCboolean (*const reset)(ALCbackend*);
ALCboolean (*const start)(ALCbackend*);
......@@ -63,7 +67,6 @@ struct ALCbackendVtable {
#define DEFINE_ALCBACKEND_VTABLE(T) \
DECLARE_THUNK(T, ALCbackend, void, Destruct) \
DECLARE_THUNK1(T, ALCbackend, ALCenum, open, const ALCchar*) \
DECLARE_THUNK(T, ALCbackend, void, close) \
DECLARE_THUNK(T, ALCbackend, ALCboolean, reset) \
DECLARE_THUNK(T, ALCbackend, ALCboolean, start) \
DECLARE_THUNK(T, ALCbackend, void, stop) \
......@@ -79,7 +82,6 @@ static const struct ALCbackendVtable T##_ALCbackend_vtable = { \
T##_ALCbackend_Destruct, \
\
T##_ALCbackend_open, \
T##_ALCbackend_close, \
T##_ALCbackend_reset, \
T##_ALCbackend_start, \
T##_ALCbackend_stop, \
......@@ -114,7 +116,7 @@ struct ALCbackendFactoryVtable {
ALCboolean (*const querySupport)(ALCbackendFactory *self, ALCbackend_Type type);
void (*const probe)(ALCbackendFactory *self, enum DevProbe type);
void (*const probe)(ALCbackendFactory *self, enum DevProbe type, al_string *outnames);
ALCbackend* (*const createBackend)(ALCbackendFactory *self, ALCdevice *device, ALCbackend_Type type);
};
......@@ -123,7 +125,7 @@ struct ALCbackendFactoryVtable {
DECLARE_THUNK(T, ALCbackendFactory, ALCboolean, init) \
DECLARE_THUNK(T, ALCbackendFactory, void, deinit) \
DECLARE_THUNK1(T, ALCbackendFactory, ALCboolean, querySupport, ALCbackend_Type) \
DECLARE_THUNK1(T, ALCbackendFactory, void, probe, enum DevProbe) \
DECLARE_THUNK2(T, ALCbackendFactory, void, probe, enum DevProbe, al_string*) \
DECLARE_THUNK2(T, ALCbackendFactory, ALCbackend*, createBackend, ALCdevice*, ALCbackend_Type) \
\
static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \
......@@ -137,17 +139,40 @@ static const struct ALCbackendFactoryVtable T##_ALCbackendFactory_vtable = { \
ALCbackendFactory *ALCpulseBackendFactory_getFactory(void);
ALCbackendFactory *ALCalsaBackendFactory_getFactory(void);
ALCbackendFactory *ALCcoreAudioBackendFactory_getFactory(void);
ALCbackendFactory *ALCossBackendFactory_getFactory(void);
ALCbackendFactory *ALCjackBackendFactory_getFactory(void);
ALCbackendFactory *ALCsolarisBackendFactory_getFactory(void);
ALCbackendFactory *ALCmmdevBackendFactory_getFactory(void);
ALCbackendFactory *SndioBackendFactory_getFactory(void);
ALCbackendFactory *ALCqsaBackendFactory_getFactory(void);
ALCbackendFactory *ALCwasapiBackendFactory_getFactory(void);
ALCbackendFactory *ALCdsoundBackendFactory_getFactory(void);
ALCbackendFactory *ALCwinmmBackendFactory_getFactory(void);
ALCbackendFactory *ALCportBackendFactory_getFactory(void);
ALCbackendFactory *ALCopenslBackendFactory_getFactory(void);
ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
ALCbackendFactory *ALCwaveBackendFactory_getFactory(void);
ALCbackendFactory *ALCsdl2BackendFactory_getFactory(void);
ALCbackendFactory *ALCloopbackFactory_getFactory(void);
ALCbackend *create_backend_wrapper(ALCdevice *device, const BackendFuncs *funcs, ALCbackend_Type type);
inline void ALCdevice_Lock(ALCdevice *device)
{ V0(device->Backend,lock)(); }
inline void ALCdevice_Unlock(ALCdevice *device)
{ V0(device->Backend,unlock)(); }
inline ClockLatency GetClockLatency(ALCdevice *device)
{
ClockLatency ret = V0(device->Backend,getClockLatency)();
ret.Latency += device->FixedLatency;
return ret;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* AL_BACKENDS_BASE_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -35,7 +35,6 @@ typedef struct ALCloopback {
static void ALCloopback_Construct(ALCloopback *self, ALCdevice *device);
static DECLARE_FORWARD(ALCloopback, ALCbackend, void, Destruct)
static ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name);
static void ALCloopback_close(ALCloopback *self);
static ALCboolean ALCloopback_reset(ALCloopback *self);
static ALCboolean ALCloopback_start(ALCloopback *self);
static void ALCloopback_stop(ALCloopback *self);
......@@ -59,14 +58,10 @@ static ALCenum ALCloopback_open(ALCloopback *self, const ALCchar *name)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
al_string_copy_cstr(&device->DeviceName, name);
alstr_copy_cstr(&device->DeviceName, name);
return ALC_NO_ERROR;
}
static void ALCloopback_close(ALCloopback* UNUSED(self))
{
}
static ALCboolean ALCloopback_reset(ALCloopback *self)
{
SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
......@@ -92,7 +87,7 @@ ALCbackendFactory *ALCloopbackFactory_getFactory(void);
static ALCboolean ALCloopbackFactory_init(ALCloopbackFactory *self);
static DECLARE_FORWARD(ALCloopbackFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory *self, ALCbackend_Type type);
static void ALCloopbackFactory_probe(ALCloopbackFactory *self, enum DevProbe type);
static void ALCloopbackFactory_probe(ALCloopbackFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCloopbackFactory_createBackend(ALCloopbackFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCloopbackFactory);
......@@ -115,7 +110,7 @@ static ALCboolean ALCloopbackFactory_querySupport(ALCloopbackFactory* UNUSED(sel
return ALC_FALSE;
}
static void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type))
static void ALCloopbackFactory_probe(ALCloopbackFactory* UNUSED(self), enum DevProbe UNUSED(type), al_string* UNUSED(outnames))
{
}
......
......@@ -36,7 +36,7 @@
typedef struct ALCnullBackend {
DERIVE_FROM_TYPE(ALCbackend);
volatile int killNow;
ATOMIC(int) killNow;
althrd_t thread;
} ALCnullBackend;
......@@ -45,7 +45,6 @@ static int ALCnullBackend_mixerProc(void *ptr);
static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device);
static DECLARE_FORWARD(ALCnullBackend, ALCbackend, void, Destruct)
static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name);
static void ALCnullBackend_close(ALCnullBackend *self);
static ALCboolean ALCnullBackend_reset(ALCnullBackend *self);
static ALCboolean ALCnullBackend_start(ALCnullBackend *self);
static void ALCnullBackend_stop(ALCnullBackend *self);
......@@ -66,6 +65,8 @@ static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device)
{
ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device);
SET_VTABLE2(ALCnullBackend, ALCbackend, self);
ATOMIC_INIT(&self->killNow, AL_TRUE);
}
......@@ -87,7 +88,8 @@ static int ALCnullBackend_mixerProc(void *ptr)
ERR("Failed to get starting time\n");
return 1;
}
while(!self->killNow && device->Connected)
while(!ATOMIC_LOAD(&self->killNow, almemory_order_acquire) &&
ATOMIC_LOAD(&device->Connected, almemory_order_acquire))
{
if(altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
{
......@@ -109,7 +111,9 @@ static int ALCnullBackend_mixerProc(void *ptr)
al_nssleep(restTime);
else while(avail-done >= device->UpdateSize)
{
ALCnullBackend_lock(self);
aluMixData(device, NULL, device->UpdateSize);
ALCnullBackend_unlock(self);
done += device->UpdateSize;
}
}
......@@ -128,15 +132,11 @@ static ALCenum ALCnullBackend_open(ALCnullBackend *self, const ALCchar *name)
return ALC_INVALID_VALUE;
device = STATIC_CAST(ALCbackend, self)->mDevice;
al_string_copy_cstr(&device->DeviceName, name);
alstr_copy_cstr(&device->DeviceName, name);
return ALC_NO_ERROR;
}
static void ALCnullBackend_close(ALCnullBackend* UNUSED(self))
{
}
static ALCboolean ALCnullBackend_reset(ALCnullBackend *self)
{
SetDefaultWFXChannelOrder(STATIC_CAST(ALCbackend, self)->mDevice);
......@@ -145,7 +145,7 @@ static ALCboolean ALCnullBackend_reset(ALCnullBackend *self)
static ALCboolean ALCnullBackend_start(ALCnullBackend *self)
{
self->killNow = 0;
ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release);
if(althrd_create(&self->thread, ALCnullBackend_mixerProc, self) != althrd_success)
return ALC_FALSE;
return ALC_TRUE;
......@@ -155,10 +155,8 @@ static void ALCnullBackend_stop(ALCnullBackend *self)
{
int res;
if(self->killNow)
if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel))
return;
self->killNow = 1;
althrd_join(self->thread, &res);
}
......@@ -173,7 +171,7 @@ ALCbackendFactory *ALCnullBackendFactory_getFactory(void);
static ALCboolean ALCnullBackendFactory_init(ALCnullBackendFactory *self);
static DECLARE_FORWARD(ALCnullBackendFactory, ALCbackendFactory, void, deinit)
static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory *self, ALCbackend_Type type);
static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type);
static void ALCnullBackendFactory_probe(ALCnullBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCnullBackendFactory_createBackend(ALCnullBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCnullBackendFactory);
......@@ -197,14 +195,13 @@ static ALCboolean ALCnullBackendFactory_querySupport(ALCnullBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCnullBackendFactory_probe(ALCnullBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(nullDevice);
break;
case CAPTURE_DEVICE_PROBE:
alstr_append_range(outnames, nullDevice, nullDevice+sizeof(nullDevice));
break;
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -26,6 +26,8 @@
#include "alMain.h"
#include "alu.h"
#include "alconfig.h"
#include "ringbuffer.h"
#include "compat.h"
#include "backends/base.h"
......@@ -139,7 +141,6 @@ static int ALCportPlayback_WriteCallback(const void *inputBuffer, void *outputBu
static void ALCportPlayback_Construct(ALCportPlayback *self, ALCdevice *device);
static void ALCportPlayback_Destruct(ALCportPlayback *self);
static ALCenum ALCportPlayback_open(ALCportPlayback *self, const ALCchar *name);
static void ALCportPlayback_close(ALCportPlayback *self);
static ALCboolean ALCportPlayback_reset(ALCportPlayback *self);
static ALCboolean ALCportPlayback_start(ALCportPlayback *self);
static void ALCportPlayback_stop(ALCportPlayback *self);
......@@ -163,8 +164,9 @@ static void ALCportPlayback_Construct(ALCportPlayback *self, ALCdevice *device)
static void ALCportPlayback_Destruct(ALCportPlayback *self)
{
if(self->stream)
Pa_CloseStream(self->stream);
PaError err = self->stream ? Pa_CloseStream(self->stream) : paNoError;
if(err != paNoError)
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
self->stream = NULL;
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
......@@ -177,7 +179,9 @@ static int ALCportPlayback_WriteCallback(const void *UNUSED(inputBuffer), void *
{
ALCportPlayback *self = userData;
ALCportPlayback_lock(self);
aluMixData(STATIC_CAST(ALCbackend, self)->mDevice, outputBuffer, framesPerBuffer);
ALCportPlayback_unlock(self);
return 0;
}
......@@ -243,20 +247,12 @@ retry_open:
return ALC_INVALID_VALUE;
}
al_string_copy_cstr(&device->DeviceName, name);
alstr_copy_cstr(&device->DeviceName, name);
return ALC_NO_ERROR;
}
static void ALCportPlayback_close(ALCportPlayback *self)
{
PaError err = Pa_CloseStream(self->stream);
if(err != paNoError)
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
self->stream = NULL;
}
static ALCboolean ALCportPlayback_reset(ALCportPlayback *self)
{
ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice;
......@@ -334,7 +330,6 @@ static int ALCportCapture_ReadCallback(const void *inputBuffer, void *outputBuff
static void ALCportCapture_Construct(ALCportCapture *self, ALCdevice *device);
static void ALCportCapture_Destruct(ALCportCapture *self);
static ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name);
static void ALCportCapture_close(ALCportCapture *self);
static DECLARE_FORWARD(ALCportCapture, ALCbackend, ALCboolean, reset)
static ALCboolean ALCportCapture_start(ALCportCapture *self);
static void ALCportCapture_stop(ALCportCapture *self);
......@@ -354,16 +349,17 @@ static void ALCportCapture_Construct(ALCportCapture *self, ALCdevice *device)
SET_VTABLE2(ALCportCapture, ALCbackend, self);
self->stream = NULL;
self->ring = NULL;
}
static void ALCportCapture_Destruct(ALCportCapture *self)
{
if(self->stream)
Pa_CloseStream(self->stream);
PaError err = self->stream ? Pa_CloseStream(self->stream) : paNoError;
if(err != paNoError)
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
self->stream = NULL;
if(self->ring)
ll_ringbuffer_free(self->ring);
ll_ringbuffer_free(self->ring);
self->ring = NULL;
ALCbackend_Destruct(STATIC_CAST(ALCbackend, self));
......@@ -397,9 +393,9 @@ static ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
samples = device->UpdateSize * device->NumUpdates;
samples = maxu(samples, 100 * device->Frequency / 1000);
frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType, device->AmbiOrder);
self->ring = ll_ringbuffer_create(samples, frame_size);
self->ring = ll_ringbuffer_create(samples, frame_size, false);
if(self->ring == NULL) return ALC_INVALID_VALUE;
self->params.device = -1;
......@@ -431,7 +427,7 @@ static ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
return ALC_INVALID_VALUE;
}
self->params.channelCount = ChannelsFromDevFmt(device->FmtChans);
self->params.channelCount = ChannelsFromDevFmt(device->FmtChans, device->AmbiOrder);
err = Pa_OpenStream(&self->stream, &self->params, NULL,
device->Frequency, paFramesPerBufferUnspecified, paNoFlag,
......@@ -443,22 +439,11 @@ static ALCenum ALCportCapture_open(ALCportCapture *self, const ALCchar *name)
return ALC_INVALID_VALUE;
}
al_string_copy_cstr(&device->DeviceName, name);
alstr_copy_cstr(&device->DeviceName, name);
return ALC_NO_ERROR;
}
static void ALCportCapture_close(ALCportCapture *self)
{
PaError err = Pa_CloseStream(self->stream);
if(err != paNoError)
ERR("Error closing stream: %s\n", Pa_GetErrorText(err));
self->stream = NULL;
ll_ringbuffer_free(self->ring);
self->ring = NULL;
}
static ALCboolean ALCportCapture_start(ALCportCapture *self)
{
......@@ -499,9 +484,8 @@ typedef struct ALCportBackendFactory {
static ALCboolean ALCportBackendFactory_init(ALCportBackendFactory *self);
static void ALCportBackendFactory_deinit(ALCportBackendFactory *self);
static ALCboolean ALCportBackendFactory_querySupport(ALCportBackendFactory *self, ALCbackend_Type type);
static void ALCportBackendFactory_probe(ALCportBackendFactory *self, enum DevProbe type);
static void ALCportBackendFactory_probe(ALCportBackendFactory *self, enum DevProbe type, al_string *outnames);
static ALCbackend* ALCportBackendFactory_createBackend(ALCportBackendFactory *self, ALCdevice *device, ALCbackend_Type type);
DEFINE_ALCBACKENDFACTORY_VTABLE(ALCportBackendFactory);
......@@ -533,15 +517,13 @@ static ALCboolean ALCportBackendFactory_querySupport(ALCportBackendFactory* UNUS
return ALC_FALSE;
}
static void ALCportBackendFactory_probe(ALCportBackendFactory* UNUSED(self), enum DevProbe type)
static void ALCportBackendFactory_probe(ALCportBackendFactory* UNUSED(self), enum DevProbe type, al_string *outnames)
{
switch(type)
{
case ALL_DEVICE_PROBE:
AppendAllDevicesList(pa_device);
break;
case CAPTURE_DEVICE_PROBE:
AppendCaptureDeviceList(pa_device);
alstr_append_range(outnames, pa_device, pa_device+sizeof(pa_device));
break;
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -3,22 +3,55 @@
#include "alMain.h"
/* These are the necessary scales for first-order HF responses to play over
* higher-order 2D (non-periphonic) decoders.
*/
#define W_SCALE_2H0P 1.224744871f /* sqrt(1.5) */
#define XYZ_SCALE_2H0P 1.0f
#define W_SCALE_3H0P 1.414213562f /* sqrt(2) */
#define XYZ_SCALE_3H0P 1.082392196f
/* These are the necessary scales for first-order HF responses to play over
* higher-order 3D (periphonic) decoders.
*/
#define W_SCALE_2H2P 1.341640787f /* sqrt(1.8) */
#define XYZ_SCALE_2H2P 1.0f
#define W_SCALE_3H3P 1.695486018f
#define XYZ_SCALE_3H3P 1.136697713f
/* NOTE: These are scale factors as applied to Ambisonics content. Decoder
* coefficients should be divided by these values to get proper N3D scalings.
*/
const ALfloat N3D2N3DScale[MAX_AMBI_COEFFS];
const ALfloat SN3D2N3DScale[MAX_AMBI_COEFFS];
const ALfloat FuMa2N3DScale[MAX_AMBI_COEFFS];
struct AmbDecConf;
struct BFormatDec;
struct AmbiUpsampler;
enum BFormatDecFlags {
BFDF_DistanceComp = 1<<0
};
struct BFormatDec *bformatdec_alloc();
void bformatdec_free(struct BFormatDec *dec);
int bformatdec_getOrder(const struct BFormatDec *dec);
void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALuint chancount, ALuint srate, const ALuint chanmap[MAX_OUTPUT_CHANNELS], int flags);
void bformatdec_free(struct BFormatDec **dec);
void bformatdec_reset(struct BFormatDec *dec, const struct AmbDecConf *conf, ALsizei chancount, ALuint srate, const ALsizei chanmap[MAX_OUTPUT_CHANNELS]);
/* Decodes the ambisonic input to the given output channels. */
void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALuint OutChannels, ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint SamplesToDo);
void bformatdec_process(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei SamplesToDo);
/* Up-samples a first-order input to the decoder's configuration. */
void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALfloat (*restrict InSamples)[BUFFERSIZE], ALuint InChannels, ALuint SamplesToDo);
void bformatdec_upSample(struct BFormatDec *dec, ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei InChannels, ALsizei SamplesToDo);
/* Stand-alone first-order upsampler. Kept here because it shares some stuff
* with bformatdec. Assumes a periphonic (4-channel) input mix!
*/
struct AmbiUpsampler *ambiup_alloc();
void ambiup_free(struct AmbiUpsampler **ambiup);
void ambiup_reset(struct AmbiUpsampler *ambiup, const ALCdevice *device, ALfloat w_scale, ALfloat xyz_scale);
void ambiup_process(struct AmbiUpsampler *ambiup, ALfloat (*restrict OutBuffer)[BUFFERSIZE], ALsizei OutChannels, const ALfloat (*restrict InSamples)[BUFFERSIZE], ALsizei SamplesToDo);
#endif /* BFORMATDEC_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef CPU_CAPS_H
#define CPU_CAPS_H
extern int CPUCapFlags;
enum {
CPU_CAP_SSE = 1<<0,
CPU_CAP_SSE2 = 1<<1,
CPU_CAP_SSE3 = 1<<2,
CPU_CAP_SSE4_1 = 1<<3,
CPU_CAP_NEON = 1<<4,
};
void FillCPUCaps(int capfilter);
#endif /* CPU_CAPS_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment