Android .so for OpenAL

master
Marc Salem 2011-12-16 18:14:00 -08:00
parent 0396174008
commit bfb1c2ec84
73 changed files with 27021 additions and 0 deletions

15
AndroidManifest.xml Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.apportable.openal_soft"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name" android:icon="@drawable/icon">
<activity android:name="openal_soft"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

17
build.properties Normal file
View File

@ -0,0 +1,17 @@
# This file is used to override default values used by the Ant build system.
#
# This file must be checked in Version Control Systems, as it is
# integral to the build system of your project.
# This file is only used by the Ant script.
# You can use this to override default values such as
# 'source.dir' for the location of your java source folder and
# 'out.dir' for the location of your output folder.
# You can also use it define how the release builds are signed by declaring
# the following properties:
# 'key.store' for the location of your keystore and
# 'key.alias' for the name of the key to use.
# The password will be asked during the build when you use the 'release' target.

79
build.xml Normal file
View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="openal_soft" default="help">
<!-- The local.properties file is created and updated by the 'android'
tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the
default property values used by the Ant rules.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android'
tool, as well as ADT.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<property file="default.properties" />
<!-- Required pre-setup import -->
<import file="${sdk.dir}/tools/ant/pre_setup.xml" />
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
[This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir}]
<target name="-post-compile">
</target>
-->
<!-- Execute the Android Setup task that will setup some properties
specific to the target, and import the build rules files.
The rules file is imported from
<SDK>/tools/ant/
Depending on the project type it can be either:
- main_rules.xml
- lib_rules.xml
- test_rules.xml
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<setup> task.
- customize it to your needs.
- Customize the whole script.
- copy/paste the content of the rules files (minus the top node)
into this file, *after* the <setup> task
- disable the import of the rules by changing the setup task
below to <setup import="false" />.
- customize to your needs.
-->
<setup />
</project>

11
default.properties Normal file
View File

@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-8

67
jni/Android.mk Normal file
View File

@ -0,0 +1,67 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OPENAL_DIR := OpenAL
LOCAL_LDLIBS := -llog
LOCAL_MODULE := openal
LOCAL_ARM_MODE := arm
LOCAL_CFLAGS += -I$(OPENAL_DIR) \
-I$(OPENAL_DIR)/include \
-I$(OPENAL_DIR)/OpenAL32/Include \
-DAL_BUILD_LIBRARY \
-DAL_ALEXT_PROTOTYPES \
-DANDROID \
-fpic \
-ffunction-sections \
-funwind-tables \
-fstack-protector \
-fno-short-enums \
-D__ARM_ARCH_5__ \
-D__ANDROID__ \
-march=armv5 \
-msoft-float \
# -DVERDE_USE_REAL_FILE_IO \
# FIXME
LOCAL_CFLAGS += -I/Developer/AndroidNDK/platforms/android-8/arch-arm/usr/include
# Default to Fixed-point math
LOCAL_CFLAGS += -DOPENAL_FIXED_POINT -DOPENAL_FIXED_POINT_SHIFT=16
LOCAL_SRC_FILES := $(OPENAL_DIR)/OpenAL32/alAuxEffectSlot.c \
$(OPENAL_DIR)/OpenAL32/alBuffer.c \
$(OPENAL_DIR)/OpenAL32/alDatabuffer.c \
$(OPENAL_DIR)/OpenAL32/alEffect.c \
$(OPENAL_DIR)/OpenAL32/alError.c \
$(OPENAL_DIR)/OpenAL32/alExtension.c \
$(OPENAL_DIR)/OpenAL32/alFilter.c \
$(OPENAL_DIR)/OpenAL32/alListener.c \
$(OPENAL_DIR)/OpenAL32/alSource.c \
$(OPENAL_DIR)/OpenAL32/alState.c \
$(OPENAL_DIR)/OpenAL32/alThunk.c \
$(OPENAL_DIR)/Alc/ALc.c \
$(OPENAL_DIR)/Alc/alcConfig.c \
$(OPENAL_DIR)/Alc/alcEcho.c \
$(OPENAL_DIR)/Alc/alcModulator.c \
$(OPENAL_DIR)/Alc/alcReverb.c \
$(OPENAL_DIR)/Alc/alcRing.c \
$(OPENAL_DIR)/Alc/alcThread.c \
$(OPENAL_DIR)/Alc/ALu.c \
$(OPENAL_DIR)/Alc/bs2b.c \
$(OPENAL_DIR)/Alc/null.c \
$(OPENAL_DIR)/Alc/panning.c \
$(OPENAL_DIR)/Alc/mixer.c \
$(OPENAL_DIR)/Alc/audiotrack.c \
# If building for versions after FROYO
#LOCAL_CFLAGS += -DPOST_FROYO
#LOCAL_SRC_FILES += $(OPENAL_DIR)/Alc/opensles.o
include $(BUILD_SHARED_LIBRARY)

1
jni/Application.mk Normal file
View File

@ -0,0 +1 @@
APP_ABI ?= armeabi

2343
jni/OpenAL/Alc/ALc.c Normal file

File diff suppressed because it is too large Load Diff

1092
jni/OpenAL/Alc/ALu.c Normal file

File diff suppressed because it is too large Load Diff

338
jni/OpenAL/Alc/alcConfig.c Normal file
View File

@ -0,0 +1,338 @@
/**
* 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
*/
#ifdef _WIN32
#ifdef __MINGW64__
#define _WIN32_IE 0x501
#else
#define _WIN32_IE 0x400
#endif
#endif
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "alMain.h"
#ifdef _WIN32_IE
#include <shlobj.h>
#endif
typedef struct ConfigEntry {
char *key;
char *value;
} ConfigEntry;
typedef struct ConfigBlock {
char *name;
ConfigEntry *entries;
size_t entryCount;
} ConfigBlock;
static ConfigBlock *cfgBlocks;
static size_t cfgCount;
static char buffer[1024];
static void LoadConfigFromFile(FILE *f)
{
ConfigBlock *curBlock = cfgBlocks;
ConfigEntry *ent;
while(fgets(buffer, sizeof(buffer), f))
{
size_t i = 0;
while(isspace(buffer[i]))
i++;
if(!buffer[i] || buffer[i] == '#')
continue;
memmove(buffer, buffer+i, strlen(buffer+i)+1);
if(buffer[0] == '[')
{
ConfigBlock *nextBlock;
i = 1;
while(buffer[i] && buffer[i] != ']')
i++;
if(!buffer[i])
{
AL_PRINT("config parse error: bad line \"%s\"\n", buffer);
continue;
}
buffer[i] = 0;
do {
i++;
if(buffer[i] && !isspace(buffer[i]))
{
if(buffer[i] != '#')
AL_PRINT("config warning: extra data after block: \"%s\"\n", buffer+i);
break;
}
} while(buffer[i]);
nextBlock = NULL;
for(i = 0;i < cfgCount;i++)
{
if(strcasecmp(cfgBlocks[i].name, buffer+1) == 0)
{
nextBlock = cfgBlocks+i;
// AL_PRINT("found block '%s'\n", nextBlock->name);
break;
}
}
if(!nextBlock)
{
nextBlock = realloc(cfgBlocks, (cfgCount+1)*sizeof(ConfigBlock));
if(!nextBlock)
{
AL_PRINT("config parse error: error reallocating config blocks\n");
continue;
}
cfgBlocks = nextBlock;
nextBlock = cfgBlocks+cfgCount;
cfgCount++;
nextBlock->name = strdup(buffer+1);
nextBlock->entries = NULL;
nextBlock->entryCount = 0;
// AL_PRINT("found new block '%s'\n", nextBlock->name);
}
curBlock = nextBlock;
continue;
}
/* Look for the option name */
i = 0;
while(buffer[i] && buffer[i] != '#' && buffer[i] != '=' &&
!isspace(buffer[i]))
i++;
if(!buffer[i] || buffer[i] == '#' || i == 0)
{
AL_PRINT("config parse error: malformed option line: \"%s\"\n", buffer);
continue;
}
/* Seperate the option */
if(buffer[i] != '=')
{
buffer[i++] = 0;
while(isspace(buffer[i]))
i++;
if(buffer[i] != '=')
{
AL_PRINT("config parse error: option without a value: \"%s\"\n", buffer);
continue;
}
}
/* Find the start of the value */
buffer[i++] = 0;
while(isspace(buffer[i]))
i++;
/* Check if we already have this option set */
ent = curBlock->entries;
while((size_t)(ent-curBlock->entries) < curBlock->entryCount)
{
if(strcasecmp(ent->key, buffer) == 0)
break;
ent++;
}
if((size_t)(ent-curBlock->entries) >= curBlock->entryCount)
{
/* Allocate a new option entry */
ent = realloc(curBlock->entries, (curBlock->entryCount+1)*sizeof(ConfigEntry));
if(!ent)
{
AL_PRINT("config parse error: error reallocating config entries\n");
continue;
}
curBlock->entries = ent;
ent = curBlock->entries + curBlock->entryCount;
curBlock->entryCount++;
ent->key = strdup(buffer);
ent->value = NULL;
}
/* Look for the end of the line (Null term, new-line, or #-symbol) and
eat up the trailing whitespace */
memmove(buffer, buffer+i, strlen(buffer+i)+1);
i = 0;
while(buffer[i] && buffer[i] != '#' && buffer[i] != '\n')
i++;
do {
i--;
} while(isspace(buffer[i]));
buffer[++i] = 0;
free(ent->value);
ent->value = strdup(buffer);
// AL_PRINT("found '%s' = '%s'\n", ent->key, ent->value);
}
}
void ReadALConfig(void)
{
FILE *f;
cfgBlocks = calloc(1, sizeof(ConfigBlock));
cfgBlocks->name = strdup("general");
cfgCount = 1;
#ifdef _WIN32
if(SHGetSpecialFolderPathA(NULL, buffer, CSIDL_APPDATA, FALSE) != FALSE)
{
size_t 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)
{
LoadConfigFromFile(f);
fclose(f);
}
if(getenv("HOME") && *(getenv("HOME")))
{
snprintf(buffer, sizeof(buffer), "%s/.alsoftrc", getenv("HOME"));
f = fopen(buffer, "r");
if(f)
{
LoadConfigFromFile(f);
fclose(f);
}
}
#endif
if(getenv("ALSOFT_CONF"))
{
f = fopen(getenv("ALSOFT_CONF"), "r");
if(f)
{
LoadConfigFromFile(f);
fclose(f);
}
}
}
void FreeALConfig(void)
{
size_t i;
for(i = 0;i < cfgCount;i++)
{
size_t j;
for(j = 0;j < cfgBlocks[i].entryCount;j++)
{
free(cfgBlocks[i].entries[j].key);
free(cfgBlocks[i].entries[j].value);
}
free(cfgBlocks[i].entries);
free(cfgBlocks[i].name);
}
free(cfgBlocks);
cfgBlocks = NULL;
cfgCount = 0;
}
const char *GetConfigValue(const char *blockName, const char *keyName, const char *def)
{
size_t i, j;
if(!keyName)
return def;
if(!blockName)
blockName = "general";
for(i = 0;i < cfgCount;i++)
{
if(strcasecmp(cfgBlocks[i].name, blockName) != 0)
continue;
for(j = 0;j < cfgBlocks[i].entryCount;j++)
{
if(strcasecmp(cfgBlocks[i].entries[j].key, keyName) == 0)
{
if(cfgBlocks[i].entries[j].value[0])
return cfgBlocks[i].entries[j].value;
return def;
}
}
}
return def;
}
int ConfigValueExists(const char *blockName, const char *keyName)
{
const char *val = GetConfigValue(blockName, keyName, "");
return !!val[0];
}
int GetConfigValueInt(const char *blockName, const char *keyName, int def)
{
const char *val = GetConfigValue(blockName, keyName, "");
if(!val[0]) return def;
return strtol(val, NULL, 0);
}
float GetConfigValueFloat(const char *blockName, const char *keyName, float def)
{
const char *val = GetConfigValue(blockName, keyName, "");
if(!val[0]) return def;
#ifdef HAVE_STRTOF
return strtof(val, NULL);
#else
return (float)strtod(val, NULL);
#endif
}
int GetConfigValueBool(const char *blockName, const char *keyName, int def)
{
const char *val = GetConfigValue(blockName, keyName, "");
if(!val[0]) return !!def;
return (strcasecmp(val, "true") == 0 || strcasecmp(val, "yes") == 0 ||
strcasecmp(val, "on") == 0 || atoi(val) != 0);
}

203
jni/OpenAL/Alc/alcEcho.c Normal file
View File

@ -0,0 +1,203 @@
/**
* 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;
}

View File

@ -0,0 +1,229 @@
/**
* 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;
}

1371
jni/OpenAL/Alc/alcReverb.c Normal file

File diff suppressed because it is too large Load Diff

131
jni/OpenAL/Alc/alcRing.c Normal file
View File

@ -0,0 +1,131 @@
/**
* 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 <string.h>
#include <stdlib.h>
#include "alMain.h"
struct RingBuffer {
ALubyte *mem;
ALsizei frame_size;
ALsizei length;
ALint read_pos;
ALint write_pos;
CRITICAL_SECTION cs;
};
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length)
{
RingBuffer *ring = calloc(1, sizeof(*ring));
if(ring)
{
ring->frame_size = frame_size;
ring->length = length+1;
ring->write_pos = 1;
ring->mem = malloc(ring->length * ring->frame_size);
if(!ring->mem)
{
free(ring);
ring = NULL;
}
InitializeCriticalSection(&ring->cs);
}
return ring;
}
void DestroyRingBuffer(RingBuffer *ring)
{
if(ring)
{
DeleteCriticalSection(&ring->cs);
free(ring->mem);
free(ring);
}
}
ALsizei RingBufferSize(RingBuffer *ring)
{
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)
{
int remain;
EnterCriticalSection(&ring->cs);
remain = (ring->read_pos-ring->write_pos+ring->length) % ring->length;
if(remain < len) len = remain;
if(len > 0)
{
remain = ring->length - ring->write_pos;
if(remain < len)
{
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,
remain*ring->frame_size);
memcpy(ring->mem, data+(remain*ring->frame_size),
(len-remain)*ring->frame_size);
}
else
memcpy(ring->mem+(ring->write_pos*ring->frame_size), data,
len*ring->frame_size);
ring->write_pos += len;
ring->write_pos %= ring->length;
}
LeaveCriticalSection(&ring->cs);
}
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
{
int remain;
EnterCriticalSection(&ring->cs);
remain = ring->length - ring->read_pos;
if(remain < len)
{
memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), remain*ring->frame_size);
memcpy(data+(remain*ring->frame_size), ring->mem, (len-remain)*ring->frame_size);
}
else
memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), len*ring->frame_size);
ring->read_pos += len;
ring->read_pos %= ring->length;
LeaveCriticalSection(&ring->cs);
}

128
jni/OpenAL/Alc/alcThread.c Normal file
View File

@ -0,0 +1,128 @@
/**
* 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

1048
jni/OpenAL/Alc/alsa.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
typedef struct {
void (*alc_android_suspend)();
void (*alc_android_resume)();
void (*alc_android_set_java_vm)(JavaVM*);
#ifdef HAVE_OPENSLES
SLEngineItf (*alc_opensles_get_native_audio_engine_engine)();
SLEngineItf (*alc_opensles_get_native_audio_output_mix)();
SLresult (*alc_opensles_create_native_audio_engine)();
#endif
} ApportableOpenALFuncs;
ApportableOpenALFuncs apportableOpenALFuncs;

320
jni/OpenAL/Alc/audiotrack.c Executable file
View File

@ -0,0 +1,320 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 2010 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 <stdlib.h>
#include <jni.h>
#include <pthread.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "apportable_openal_funcs.h"
static const ALCchar android_device[] = "Android Default";
static JavaVM* javaVM = NULL;
static JNIEnv* env;
static jclass cAudioTrack = NULL;
static jmethodID mAudioTrack;
static jmethodID mGetMinBufferSize;
static jmethodID mPlay;
static jmethodID mPause;
static jmethodID mStop;
static jmethodID mRelease;
static jmethodID mWrite;
static int suspended = 0;
static int audioTrackPlaying = 0;
typedef struct
{
pthread_t thread;
volatile int running;
} AndroidData;
#define STREAM_MUSIC 3
#define CHANNEL_CONFIGURATION_MONO 2
#define CHANNEL_CONFIGURATION_STEREO 3
#define ENCODING_PCM_8BIT 3
#define ENCODING_PCM_16BIT 2
#define MODE_STREAM 1
static void* thread_function(void* arg)
{
ALCdevice* device = (ALCdevice*)arg;
AndroidData* data = (AndroidData*)device->ExtraData;
JNIEnv* env;
(*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
(*env)->PushLocalFrame(env, 2);
int sampleRateInHz = device->Frequency;
int channelConfig = ChannelsFromDevFmt(device->FmtChans) == 1 ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO;
int audioFormat = BytesFromDevFmt(device->FmtType) == 1 ? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT;
int bufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack,
mGetMinBufferSize, sampleRateInHz, channelConfig, audioFormat);
// Suggestion from Eric Wing <ewmailing@gmail.com>
/* According to the author Martins Mozelko, I should multiply bufferSizeInBytes to tune performance.
Say, multiply by 2.
But making this number smaller seems to reduce latency...
I have tried dividing by 2, 4, and 8. 8 refuses to play any sound.
It seems that this just divides out the multiplication of NumUpdates (default=4)
which returns it to min buffer size.
bufferSizeInBytes is used in multiple places and
bufferSizeInSamples is tied directly to bufferSizeInBytes though, so we need to be careful
about what we want to change.
I'm assuming Martins is correct and this is the indeed the place we want to change it.
Dividing out the bufferSizeInSamples separately and skipping the multiply did not work.
Omitting the multiply and not dividing did work, but the buffers may be unnecessarily large.
*/
bufferSizeInBytes = bufferSizeInBytes / device->NumUpdates;
int bufferSizeInSamples = bufferSizeInBytes / FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
jobject track = (*env)->NewObject(env, cAudioTrack, mAudioTrack,
STREAM_MUSIC, sampleRateInHz, channelConfig, audioFormat, device->NumUpdates * bufferSizeInBytes, MODE_STREAM);
(*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mPlay);
audioTrackPlaying = 1;
jarray buffer = (*env)->NewByteArray(env, bufferSizeInBytes);
while (data->running)
{
if (suspended) {
if (audioTrackPlaying) {
(*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mPause);
audioTrackPlaying = 0;
}
usleep(5000);
continue;
} else if (!audioTrackPlaying) {
(*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mPlay);
audioTrackPlaying = 1;
}
void* pBuffer = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
if (pBuffer)
{
aluMixData(device, pBuffer, bufferSizeInSamples);
(*env)->ReleasePrimitiveArrayCritical(env, buffer, pBuffer, 0);
(*env)->CallNonvirtualIntMethod(env, track, cAudioTrack, mWrite, buffer, 0, bufferSizeInBytes);
}
else
{
AL_PRINT("Failed to get pointer to array bytes");
}
}
(*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mStop);
(*env)->CallNonvirtualVoidMethod(env, track, cAudioTrack, mRelease);
(*env)->PopLocalFrame(env, NULL);
(*javaVM)->DetachCurrentThread(javaVM);
return NULL;
}
static ALCboolean android_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
(*javaVM)->AttachCurrentThread(javaVM, &env, NULL);
AndroidData* data;
int channels;
int bytes;
if (!cAudioTrack)
{
/* Cache AudioTrack class and it's method id's
* And do this only once!
*/
cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack");
if (!cAudioTrack)
{
AL_PRINT("android.media.AudioTrack class is not found. Are you running at least 1.5 version?");
return ALC_FALSE;
}
cAudioTrack = (*env)->NewGlobalRef(env, cAudioTrack);
mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "<init>", "(IIIIII)V");
mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I");
mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V");
mPause = (*env)->GetMethodID(env, cAudioTrack, "pause", "()V");
mStop = (*env)->GetMethodID(env, cAudioTrack, "stop", "()V");
mRelease = (*env)->GetMethodID(env, cAudioTrack, "release", "()V");
mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I");
}
if (!deviceName)
{
deviceName = android_device;
}
else if (strcmp(deviceName, android_device) != 0)
{
return ALC_FALSE;
}
data = (AndroidData*)calloc(1, sizeof(*data));
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
static void android_close_playback(ALCdevice *device)
{
AndroidData* data = (AndroidData*)device->ExtraData;
if (data != NULL)
{
free(data);
device->ExtraData = NULL;
}
}
static ALCboolean android_reset_playback(ALCdevice *device)
{
AndroidData* data = (AndroidData*)device->ExtraData;
// if (ChannelsFromDevFmt(device->FmtChans) >= 2)
// {
// device->Format = BytesFromDevFmt(device->FmtType) >= 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO8;
// }
// else
// {
// device->Format = BytesFromDevFmt(device->FmtType) >= 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8;
// }
SetDefaultChannelOrder(device);
data->running = 1;
pthread_create(&data->thread, NULL, thread_function, device);
return ALC_TRUE;
}
static void android_stop_playback(ALCdevice *device)
{
AndroidData* data = (AndroidData*)device->ExtraData;
if (data->running)
{
data->running = 0;
pthread_join(data->thread, NULL);
}
}
static ALCboolean android_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
{
(void)pDevice;
(void)deviceName;
return ALC_FALSE;
}
static void android_close_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void android_start_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void android_stop_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void android_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
(void)pDevice;
(void)pBuffer;
(void)lSamples;
}
static ALCuint android_available_samples(ALCdevice *pDevice)
{
(void)pDevice;
return 0;
}
static const BackendFuncs android_funcs = {
android_open_playback,
android_close_playback,
android_reset_playback,
android_stop_playback,
android_open_capture,
android_close_capture,
android_start_capture,
android_stop_capture,
android_capture_samples,
android_available_samples
};
static void alc_audiotrack_suspend()
{
suspended = 1;
}
static void alc_audiotrack_resume()
{
suspended = 0;
}
static void alc_audiotrack_set_java_vm(JavaVM *vm)
{
javaVM = vm;
}
void alc_audiotrack_init(BackendFuncs *func_list)
{
*func_list = android_funcs;
apportableOpenALFuncs.alc_android_suspend = alc_audiotrack_suspend;
apportableOpenALFuncs.alc_android_resume = alc_audiotrack_resume;
apportableOpenALFuncs.alc_android_set_java_vm = alc_audiotrack_set_java_vm;
}
void alc_audiotrack_deinit(void)
{
/* release cached AudioTrack class */
(*env)->DeleteGlobalRef(env, cAudioTrack);
(*javaVM)->DetachCurrentThread(javaVM);
}
void alc_audiotrack_probe(int type)
{
if (type == DEVICE_PROBE)
{
AppendDeviceList(android_device);
}
else if (type == ALL_DEVICE_PROBE)
{
AppendAllDeviceList(android_device);
}
}

209
jni/OpenAL/Alc/bs2b.c Normal file
View File

@ -0,0 +1,209 @@
/*-
* Copyright (c) 2005 Boris Mikhaylov
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include <math.h>
#include "bs2b.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
/* Single pole IIR filter.
* O[n] = a0*I[n] + a1*I[n-1] + b1*O[n-1]
*/
/* Lowpass filter */
#define lo_filter(in, out_1) (bs2b->a0_lo*(in) + bs2b->b1_lo*(out_1))
/* Highboost filter */
#define hi_filter(in, in_1, out_1) (bs2b->a0_hi*(in) + bs2b->a1_hi*(in_1) + bs2b->b1_hi*(out_1))
/* Set up all data. */
static void init(struct bs2b *bs2b)
{
double Fc_lo, Fc_hi;
double G_lo, G_hi;
double x;
if ((bs2b->srate > 192000) || (bs2b->srate < 2000))
bs2b->srate = BS2B_DEFAULT_SRATE;
switch(bs2b->level)
{
case BS2B_LOW_CLEVEL: /* Low crossfeed level */
Fc_lo = 360.0;
Fc_hi = 501.0;
G_lo = 0.398107170553497;
G_hi = 0.205671765275719;
break;
case BS2B_MIDDLE_CLEVEL: /* Middle crossfeed level */
Fc_lo = 500.0;
Fc_hi = 711.0;
G_lo = 0.459726988530872;
G_hi = 0.228208484414988;
break;
case BS2B_HIGH_CLEVEL: /* High crossfeed level (virtual speakers are closer to itself) */
Fc_lo = 700.0;
Fc_hi = 1021.0;
G_lo = 0.530884444230988;
G_hi = 0.250105790667544;
break;
case BS2B_LOW_ECLEVEL: /* Low easy crossfeed level */
Fc_lo = 360.0;
Fc_hi = 494.0;
G_lo = 0.316227766016838;
G_hi = 0.168236228897329;
break;
case BS2B_MIDDLE_ECLEVEL: /* Middle easy crossfeed level */
Fc_lo = 500.0;
Fc_hi = 689.0;
G_lo = 0.354813389233575;
G_hi = 0.187169483835901;
break;
default: /* High easy crossfeed level */
bs2b->level = BS2B_HIGH_ECLEVEL;
Fc_lo = 700.0;
Fc_hi = 975.0;
G_lo = 0.398107170553497;
G_hi = 0.205671765275719;
break;
} /* switch */
/* $fc = $Fc / $s;
* $d = 1 / 2 / pi / $fc;
* $x = exp(-1 / $d);
*/
x = exp(-2.0 * M_PI * Fc_lo / bs2b->srate);
bs2b->b1_lo = x;
bs2b->a0_lo = G_lo * (1.0 - x);
x = exp(-2.0 * M_PI * Fc_hi / bs2b->srate);
bs2b->b1_hi = x;
bs2b->a0_hi = 1.0 - G_hi * (1.0 - x);
bs2b->a1_hi = -x;
bs2b->gain = 1.0 / (1.0 - G_hi + G_lo);
} /* init */
/* Exported functions.
* See descriptions in "bs2b.h"
*/
void bs2b_set_level(struct bs2b *bs2b, int level)
{
if(level == bs2b->level)
return;
bs2b->level = level;
init(bs2b);
} /* bs2b_set_level */
int bs2b_get_level(struct bs2b *bs2b)
{
return bs2b->level;
} /* bs2b_get_level */
void bs2b_set_srate(struct bs2b *bs2b, int srate)
{
if (srate == bs2b->srate)
return;
bs2b->srate = srate;
init(bs2b);
} /* bs2b_set_srate */
int bs2b_get_srate(struct bs2b *bs2b)
{
return bs2b->srate;
} /* bs2b_get_srate */
void bs2b_clear(struct bs2b *bs2b)
{
int loopv = sizeof(bs2b->last_sample);
while (loopv)
{
((char *)&bs2b->last_sample)[--loopv] = 0;
}
} /* bs2b_clear */
int bs2b_is_clear(struct bs2b *bs2b)
{
int loopv = sizeof(bs2b->last_sample);
while (loopv)
{
if (((char *)&bs2b->last_sample)[--loopv] != 0)
return 0;
}
return 1;
} /* bs2b_is_clear */
void bs2b_cross_feed(struct bs2b *bs2b, ALfp *ALsample)
{
//FIXME fully convert to fixed point math
float sample[2];
sample[0] = ALfp2float(ALsample[0]);
sample[1] = ALfp2float(ALsample[1]);
/* Lowpass filter */
bs2b->last_sample.lo[0] = lo_filter(sample[0], bs2b->last_sample.lo[0]);
bs2b->last_sample.lo[1] = lo_filter(sample[1], bs2b->last_sample.lo[1]);
/* Highboost filter */
bs2b->last_sample.hi[0] = hi_filter(sample[0], bs2b->last_sample.asis[0], bs2b->last_sample.hi[0]);
bs2b->last_sample.hi[1] = hi_filter(sample[1], bs2b->last_sample.asis[1], bs2b->last_sample.hi[1]);
bs2b->last_sample.asis[0] = sample[0];
bs2b->last_sample.asis[1] = sample[1];
/* Crossfeed */
sample[0] = bs2b->last_sample.hi[0] + bs2b->last_sample.lo[1];
sample[1] = bs2b->last_sample.hi[1] + bs2b->last_sample.lo[0];
/* Bass boost cause allpass attenuation */
sample[0] *= bs2b->gain;
sample[1] *= bs2b->gain;
/* Clipping of overloaded samples */
#if 0
if (sample[0] > 1.0)
sample[0] = 1.0;
if (sample[0] < -1.0)
sample[0] = -1.0;
if (sample[1] > 1.0)
sample[1] = 1.0;
if (sample[1] < -1.0)
sample[1] = -1.0;
#endif
ALsample[0] = float2ALfp(sample[0]);
ALsample[1] = float2ALfp(sample[1]);
} /* bs2b_cross_feed */

612
jni/OpenAL/Alc/dsound.c Normal file
View File

@ -0,0 +1,612 @@
/**
* 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"
#define _WIN32_WINNT 0x0500
#define INITGUID
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <dsound.h>
#include <cguid.h>
#include <mmreg.h>
#ifndef _WAVEFORMATEXTENSIBLE_
#include <ks.h>
#include <ksmedia.h>
#endif
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#ifndef DSSPEAKER_5POINT1
#define DSSPEAKER_5POINT1 6
#endif
#ifndef DSSPEAKER_7POINT1
#define DSSPEAKER_7POINT1 7
#endif
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
static void *ds_handle;
static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter);
static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext);
typedef struct {
// DirectSound Playback Device
LPDIRECTSOUND lpDS;
LPDIRECTSOUNDBUFFER DSpbuffer;
LPDIRECTSOUNDBUFFER DSsbuffer;
volatile int killNow;
ALvoid *thread;
} DSoundData;
typedef struct {
ALCchar *name;
GUID guid;
} DevMap;
static const ALCchar dsDevice[] = "DirectSound Default";
static DevMap *DeviceList;
static ALuint NumDevices;
void *DSoundLoad(void)
{
if(!ds_handle)
{
#ifdef _WIN32
ds_handle = LoadLibraryA("dsound.dll");
if(ds_handle == NULL)
{
AL_PRINT("Failed to load dsound.dll\n");
return NULL;
}
#define LOAD_FUNC(f) do { \
p##f = (void*)GetProcAddress((HMODULE)ds_handle, #f); \
if(p##f == NULL) \
{ \
FreeLibrary(ds_handle); \
ds_handle = NULL; \
AL_PRINT("Could not load %s from dsound.dll\n", #f); \
return NULL; \
} \
} while(0)
#else
ds_handle = (void*)0xDEADBEEF;
#define LOAD_FUNC(f) p##f = f
#endif
LOAD_FUNC(DirectSoundCreate);
LOAD_FUNC(DirectSoundEnumerateA);
#undef LOAD_FUNC
}
return ds_handle;
}
static BOOL CALLBACK DSoundEnumDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
{
char str[1024];
void *temp;
int count;
ALuint i;
(void)data;
(void)drvname;
if(NumDevices == 0)
{
temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
if(temp)
{
DeviceList = temp;
DeviceList[NumDevices].name = strdup(dsDevice);
DeviceList[NumDevices].guid = GUID_NULL;
NumDevices++;
}
}
if(!guid)
return TRUE;
count = 0;
do {
if(count == 0)
snprintf(str, sizeof(str), "%s via DirectSound", desc);
else
snprintf(str, sizeof(str), "%s #%d via DirectSound", desc, count+1);
count++;
for(i = 0;i < NumDevices;i++)
{
if(strcmp(str, DeviceList[i].name) == 0)
break;
}
} while(i != NumDevices);
temp = realloc(DeviceList, sizeof(DevMap) * (NumDevices+1));
if(temp)
{
DeviceList = temp;
DeviceList[NumDevices].name = strdup(str);
DeviceList[NumDevices].guid = *guid;
NumDevices++;
}
return TRUE;
}
static ALuint DSoundProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
DSoundData *pData = (DSoundData*)pDevice->ExtraData;
DSBCAPS DSBCaps;
DWORD LastCursor = 0;
DWORD PlayCursor;
VOID *WritePtr1, *WritePtr2;
DWORD WriteCnt1, WriteCnt2;
BOOL Playing = FALSE;
DWORD FrameSize;
DWORD FragSize;
DWORD avail;
HRESULT err;
SetRTPriority();
memset(&DSBCaps, 0, sizeof(DSBCaps));
DSBCaps.dwSize = sizeof(DSBCaps);
err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps);
if(FAILED(err))
{
AL_PRINT("Failed to get buffer caps: 0x%lx\n", err);
aluHandleDisconnect(pDevice);
return 1;
}
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
FragSize = pDevice->UpdateSize * FrameSize;
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
while(!pData->killNow)
{
// Get current play and write cursors
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
if(avail < FragSize)
{
if(!Playing)
{
err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
if(FAILED(err))
{
AL_PRINT("Failed to play buffer: 0x%lx\n", err);
aluHandleDisconnect(pDevice);
return 1;
}
Playing = TRUE;
}
Sleep(1);
continue;
}
avail -= avail%FragSize;
// Lock output buffer
WriteCnt1 = 0;
WriteCnt2 = 0;
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
// If the buffer is lost, restore it and lock
if(err == DSERR_BUFFERLOST)
{
err = IDirectSoundBuffer_Restore(pData->DSsbuffer);
if(SUCCEEDED(err))
{
Playing = FALSE;
LastCursor = 0;
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
}
}
// Successfully locked the output buffer
if(SUCCEEDED(err))
{
// If we have an active context, mix data directly into output buffer otherwise fill with silence
aluMixData(pDevice, WritePtr1, WriteCnt1/FrameSize);
aluMixData(pDevice, WritePtr2, WriteCnt2/FrameSize);
// Unlock output buffer only when successfully locked
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
}
else
{
AL_PRINT("Buffer lock error: %#lx\n", err);
aluHandleDisconnect(pDevice);
return 1;
}
// Update old write cursor location
LastCursor += WriteCnt1+WriteCnt2;
LastCursor %= DSBCaps.dwBufferBytes;
}
return 0;
}
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
{
DSoundData *pData = NULL;
LPGUID guid = NULL;
HRESULT hr;
if(!DSoundLoad())
return ALC_FALSE;
if(!deviceName)
deviceName = dsDevice;
else if(strcmp(deviceName, dsDevice) != 0)
{
ALuint i;
if(!DeviceList)
{
hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
}
for(i = 0;i < NumDevices;i++)
{
if(strcmp(deviceName, DeviceList[i].name) == 0)
{
if(i > 0)
guid = &DeviceList[i].guid;
break;
}
}
if(i == NumDevices)
return ALC_FALSE;
}
//Initialise requested device
pData = calloc(1, sizeof(DSoundData));
if(!pData)
{
alcSetError(device, ALC_OUT_OF_MEMORY);
return ALC_FALSE;
}
//DirectSound Init code
hr = pDirectSoundCreate(guid, &pData->lpDS, NULL);
if(SUCCEEDED(hr))
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
if(FAILED(hr))
{
if(pData->lpDS)
IDirectSound_Release(pData->lpDS);
free(pData);
AL_PRINT("Device init failed: 0x%08lx\n", hr);
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = pData;
return ALC_TRUE;
}
static void DSoundClosePlayback(ALCdevice *device)
{
DSoundData *pData = device->ExtraData;
IDirectSound_Release(pData->lpDS);
free(pData);
device->ExtraData = NULL;
}
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
DSoundData *pData = (DSoundData*)device->ExtraData;
DSBUFFERDESC DSBDescription;
WAVEFORMATEXTENSIBLE OutputType;
DWORD speakers;
HRESULT hr;
memset(&OutputType, 0, sizeof(OutputType));
switch(device->FmtType)
{
case DevFmtByte:
device->FmtType = DevFmtUByte;
break;
case DevFmtUShort:
device->FmtType = DevFmtShort;
break;
case DevFmtUByte:
case DevFmtShort:
case DevFmtFloat:
break;
}
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
{
switch(device->FmtChans)
{
case DevFmtMono:
speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
break;
case DevFmtStereo:
speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
break;
case DevFmtQuad:
speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
break;
case DevFmtX51:
speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
break;
case DevFmtX61:
/* ??? */;
break;
case DevFmtX71:
speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
break;
}
}
if(SUCCEEDED(hr))
{
speakers = DSSPEAKER_CONFIG(speakers);
if(speakers == DSSPEAKER_MONO)
{
device->FmtChans = DevFmtMono;
OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
}
else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
{
device->FmtChans = DevFmtStereo;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT;
}
else if(speakers == DSSPEAKER_QUAD)
{
device->FmtChans = DevFmtQuad;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT |
SPEAKER_BACK_RIGHT;
}
else if(speakers == DSSPEAKER_5POINT1)
{
device->FmtChans = DevFmtX51;
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)
{
device->FmtChans = DevFmtX71;
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;
}
OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans);
OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 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;
}
if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
{
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
OutputType.Format.cbSize = 22;
if(OutputType.Format.wBitsPerSample == 32)
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
else
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->UpdateSize * device->NumUpdates *
OutputType.Format.nBlockAlign;
DSBDescription.lpwfxFormat=&OutputType.Format;
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
}
if(SUCCEEDED(hr))
{
SetDefaultWFXChannelOrder(device);
pData->thread = StartThread(DSoundProc, device);
if(!pData->thread)
hr = E_FAIL;
}
if(FAILED(hr))
{
if (pData->DSsbuffer)
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
if (pData->DSpbuffer)
IDirectSoundBuffer_Release(pData->DSpbuffer);
pData->DSpbuffer = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void DSoundStopPlayback(ALCdevice *device)
{
DSoundData *pData = device->ExtraData;
if(!pData->thread)
return;
pData->killNow = 1;
StopThread(pData->thread);
pData->thread = NULL;
pData->killNow = 0;
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
if (pData->DSpbuffer)
IDirectSoundBuffer_Release(pData->DSpbuffer);
pData->DSpbuffer = NULL;
}
static ALCboolean DSoundOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
(void)pDevice;
(void)deviceName;
return ALC_FALSE;
}
static void DSoundCloseCapture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void DSoundStartCapture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void DSoundStopCapture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void DSoundCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
(void)pDevice;
(void)pBuffer;
(void)lSamples;
}
static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
{
(void)pDevice;
return 0;
}
BackendFuncs DSoundFuncs = {
DSoundOpenPlayback,
DSoundClosePlayback,
DSoundResetPlayback,
DSoundStopPlayback,
DSoundOpenCapture,
DSoundCloseCapture,
DSoundStartCapture,
DSoundStopCapture,
DSoundCaptureSamples,
DSoundAvailableSamples
};
void alcDSoundInit(BackendFuncs *FuncList)
{
*FuncList = DSoundFuncs;
}
void alcDSoundDeinit(void)
{
ALuint i;
for(i = 0;i < NumDevices;++i)
free(DeviceList[i].name);
free(DeviceList);
DeviceList = NULL;
NumDevices = 0;
if(ds_handle)
{
#ifdef _WIN32
FreeLibrary(ds_handle);
#endif
ds_handle = NULL;
}
}
void alcDSoundProbe(int type)
{
if(!DSoundLoad()) return;
if(type == DEVICE_PROBE)
AppendDeviceList(dsDevice);
else if(type == ALL_DEVICE_PROBE)
{
HRESULT hr;
ALuint i;
for(i = 0;i < NumDevices;++i)
free(DeviceList[i].name);
free(DeviceList);
DeviceList = NULL;
NumDevices = 0;
hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL);
if(FAILED(hr))
AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
else
{
for(i = 0;i < NumDevices;i++)
AppendAllDeviceList(DeviceList[i].name);
}
}
}

813
jni/OpenAL/Alc/mixer.c Normal file
View File

@ -0,0 +1,813 @@
/**
* 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 <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "alSource.h"
#include "alBuffer.h"
#include "alListener.h"
#include "alAuxEffectSlot.h"
#include "alu.h"
#include "bs2b.h"
static __inline ALdfp point32(const ALfp *vals, ALint step, ALint frac)
{ return vals[0]; (void)step; (void)frac; }
static __inline ALdfp lerp32(const ALfp *vals, ALint step, ALint frac)
{ return lerp(vals[0], vals[step], ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE)))); }
static __inline ALdfp cubic32(const ALfp *vals, ALint step, ALint frac)
{ return cubic(vals[-step], vals[0], vals[step], vals[step+step],
ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE)))); }
static __inline ALdfp point16(const ALshort *vals, ALint step, ALint frac)
{ return ALfpMult(int2ALfp(vals[0]), float2ALfp(1.0/32767.0)); (void)step; (void)frac; }
static __inline ALdfp lerp16(const ALshort *vals, ALint step, ALint frac)
{ return ALfpMult(lerp(int2ALfp(vals[0]), int2ALfp(vals[step]), ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE)))),
float2ALfp(1.0/32767.0)); }
static __inline ALdfp cubic16(const ALshort *vals, ALint step, ALint frac)
{ return ALfpMult(cubic(int2ALfp(vals[-step]), int2ALfp(vals[0]), int2ALfp(vals[step]), int2ALfp(vals[step+step]),
ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE)))), float2ALfp(1.0/32767.0)); }
static __inline ALdfp point8(const ALubyte *vals, ALint step, ALint frac)
{ return ALfpMult(int2ALfp((int)vals[0]-128), float2ALfp(1.0/127.0)); (void)step; (void)frac; }
static __inline ALdfp lerp8(const ALubyte *vals, ALint step, ALint frac)
{ return ALfpMult((lerp(int2ALfp(vals[0]), int2ALfp(vals[step]),
ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE))))-
int2ALfp(128)),
float2ALfp(1.0/127.0)); }
static __inline ALdfp cubic8(const ALubyte *vals, ALint step, ALint frac)
{ return ALfpMult((cubic(int2ALfp(vals[-step]), int2ALfp(vals[0]), int2ALfp(vals[step]), int2ALfp(vals[step+step]),
ALfpMult(int2ALfp(frac), ALfpDiv(int2ALfp(1),int2ALfp(FRACTIONONE))))-
int2ALfp(128)),
float2ALfp(1.0/127.0)); }
#define DECL_TEMPLATE(T, sampler) \
static void Mix_##T##_1_##sampler(ALsource *Source, ALCdevice *Device, \
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
ALfp (*DryBuffer)[MAXCHANNELS]; \
ALfp *ClickRemoval, *PendingClicks; \
ALuint pos, frac; \
ALfp DrySend[MAXCHANNELS]; \
FILTER *DryFilter; \
ALuint BufferIdx; \
ALuint increment; \
ALuint out, c; \
ALfp value; \
\
increment = Source->Params.Step; \
\
DryBuffer = Device->DryBuffer; \
ClickRemoval = Device->ClickRemoval; \
PendingClicks = Device->PendingClicks; \
DryFilter = &Source->Params.iirFilter; \
for(c = 0;c < MAXCHANNELS;c++) \
DrySend[c] = Source->Params.DryGains[0][c]; \
\
pos = 0; \
frac = *DataPosFrac; \
\
if(OutPos == 0) \
{ \
value = sampler(data+pos, 1, frac); \
\
value = lpFilter4PC(DryFilter, 0, value); \
for(c = 0;c < MAXCHANNELS;c++) \
ClickRemoval[c] = (ClickRemoval[c] - ALfpMult(value,DrySend[c])); \
} \
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
{ \
/* First order interpolator */ \
value = sampler(data+pos, 1, frac); \
\
/* Direct path final mix buffer and panning */ \
value = lpFilter4P(DryFilter, 0, value); \
for(c = 0;c < MAXCHANNELS;c++) \
DryBuffer[OutPos][c] = (DryBuffer[OutPos][c] + ALfpMult(value,DrySend[c])); \
\
frac += increment; \
pos += frac>>FRACTIONBITS; \
frac &= FRACTIONMASK; \
OutPos++; \
} \
if(OutPos == SamplesToDo) \
{ \
value = sampler(data+pos, 1, frac); \
\
value = lpFilter4PC(DryFilter, 0, value); \
for(c = 0;c < MAXCHANNELS;c++) \
PendingClicks[c] = (PendingClicks[c] + ALfpMult(value,DrySend[c])); \
} \
\
for(out = 0;out < Device->NumAuxSends;out++) \
{ \
ALfp WetSend; \
ALfp *WetBuffer; \
ALfp *WetClickRemoval; \
ALfp *WetPendingClicks; \
FILTER *WetFilter; \
\
if(!Source->Send[out].Slot || \
Source->Send[out].Slot->effect.type == AL_EFFECT_NULL) \
continue; \
\
WetBuffer = Source->Send[out].Slot->WetBuffer; \
WetClickRemoval = Source->Send[out].Slot->ClickRemoval; \
WetPendingClicks = Source->Send[out].Slot->PendingClicks; \
WetFilter = &Source->Params.Send[out].iirFilter; \
WetSend = Source->Params.Send[out].WetGain; \
\
pos = 0; \
frac = *DataPosFrac; \
OutPos -= BufferSize; \
\
if(OutPos == 0) \
{ \
value = sampler(data+pos, 1, frac); \
\
value = lpFilter2PC(WetFilter, 0, value); \
WetClickRemoval[0] = (WetClickRemoval[0] - ALfpMult(value,WetSend)); \
} \
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
{ \
/* First order interpolator */ \
value = sampler(data+pos, 1, frac); \
\
/* Room path final mix buffer and panning */ \
value = lpFilter2P(WetFilter, 0, value); \
WetBuffer[OutPos] = (WetBuffer[OutPos] + ALfpMult(value,WetSend)); \
\
frac += increment; \
pos += frac>>FRACTIONBITS; \
frac &= FRACTIONMASK; \
OutPos++; \
} \
if(OutPos == SamplesToDo) \
{ \
value = sampler(data+pos, 1, frac); \
\
value = lpFilter2PC(WetFilter, 0, value); \
WetPendingClicks[0] = (WetPendingClicks[0] + ALfpMult(value,WetSend)); \
} \
} \
*DataPosInt += pos; \
*DataPosFrac = frac; \
}
DECL_TEMPLATE(ALfp, point32)
DECL_TEMPLATE(ALfp, lerp32)
DECL_TEMPLATE(ALfp, cubic32)
DECL_TEMPLATE(ALshort, point16)
DECL_TEMPLATE(ALshort, lerp16)
DECL_TEMPLATE(ALshort, cubic16)
DECL_TEMPLATE(ALubyte, point8)
DECL_TEMPLATE(ALubyte, lerp8)
DECL_TEMPLATE(ALubyte, cubic8)
#undef DECL_TEMPLATE
#define DECL_TEMPLATE(T, chnct, sampler) \
static void Mix_##T##_##chnct##_##sampler(ALsource *Source, ALCdevice *Device,\
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
const ALuint Channels = chnct; \
const ALfp scaler = ALfpDiv(int2ALfp(1),int2ALfp(chnct)); \
ALfp (*DryBuffer)[MAXCHANNELS]; \
ALfp *ClickRemoval, *PendingClicks; \
ALuint pos, frac; \
ALfp DrySend[chnct][MAXCHANNELS]; \
FILTER *DryFilter; \
ALuint BufferIdx; \
ALuint increment; \
ALuint i, out, c; \
ALfp value; \
\
increment = Source->Params.Step; \
\
DryBuffer = Device->DryBuffer; \
ClickRemoval = Device->ClickRemoval; \
PendingClicks = Device->PendingClicks; \
DryFilter = &Source->Params.iirFilter; \
for(i = 0;i < Channels;i++) \
{ \
for(c = 0;c < MAXCHANNELS;c++) \
DrySend[i][c] = Source->Params.DryGains[i][c]; \
} \
\
pos = 0; \
frac = *DataPosFrac; \
\
if(OutPos == 0) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter2PC(DryFilter, i*2, value); \
for(c = 0;c < MAXCHANNELS;c++) \
ClickRemoval[c] = (ClickRemoval[c] - ALfpMult(value,DrySend[i][c])); \
} \
} \
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter2P(DryFilter, i*2, value); \
for(c = 0;c < MAXCHANNELS;c++) \
DryBuffer[OutPos][c] = (DryBuffer[OutPos][c] + ALfpMult(value,DrySend[i][c])); \
} \
\
frac += increment; \
pos += frac>>FRACTIONBITS; \
frac &= FRACTIONMASK; \
OutPos++; \
} \
if(OutPos == SamplesToDo) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter2PC(DryFilter, i*2, value); \
for(c = 0;c < MAXCHANNELS;c++) \
PendingClicks[c] = (PendingClicks[c] + ALfpMult(value,DrySend[i][c])); \
} \
} \
\
for(out = 0;out < Device->NumAuxSends;out++) \
{ \
ALfp WetSend; \
ALfp *WetBuffer; \
ALfp *WetClickRemoval; \
ALfp *WetPendingClicks; \
FILTER *WetFilter; \
\
if(!Source->Send[out].Slot || \
Source->Send[out].Slot->effect.type == AL_EFFECT_NULL) \
continue; \
\
WetBuffer = Source->Send[out].Slot->WetBuffer; \
WetClickRemoval = Source->Send[out].Slot->ClickRemoval; \
WetPendingClicks = Source->Send[out].Slot->PendingClicks; \
WetFilter = &Source->Params.Send[out].iirFilter; \
WetSend = Source->Params.Send[out].WetGain; \
\
pos = 0; \
frac = *DataPosFrac; \
OutPos -= BufferSize; \
\
if(OutPos == 0) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter1PC(WetFilter, i, value); \
WetClickRemoval[0] = (WetClickRemoval[0] - ALfpMult(ALfpMult(value,WetSend), scaler)); \
} \
} \
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter1P(WetFilter, i, value); \
WetBuffer[OutPos] = (WetBuffer[OutPos] + ALfpMult(ALfpMult(value,WetSend), scaler)); \
} \
\
frac += increment; \
pos += frac>>FRACTIONBITS; \
frac &= FRACTIONMASK; \
OutPos++; \
} \
if(OutPos == SamplesToDo) \
{ \
for(i = 0;i < Channels;i++) \
{ \
value = sampler(data + pos*Channels + i, Channels, frac); \
\
value = lpFilter1PC(WetFilter, i, value); \
WetPendingClicks[0] = (WetPendingClicks[0] + ALfpMult(ALfpMult(value,WetSend), scaler)); \
} \
} \
} \
*DataPosInt += pos; \
*DataPosFrac = frac; \
}
DECL_TEMPLATE(ALfp, 2, point32)
DECL_TEMPLATE(ALfp, 2, lerp32)
DECL_TEMPLATE(ALfp, 2, cubic32)
DECL_TEMPLATE(ALshort, 2, point16)
DECL_TEMPLATE(ALshort, 2, lerp16)
DECL_TEMPLATE(ALshort, 2, cubic16)
DECL_TEMPLATE(ALubyte, 2, point8)
DECL_TEMPLATE(ALubyte, 2, lerp8)
DECL_TEMPLATE(ALubyte, 2, cubic8)
DECL_TEMPLATE(ALfp, 4, point32)
DECL_TEMPLATE(ALfp, 4, lerp32)
DECL_TEMPLATE(ALfp, 4, cubic32)
DECL_TEMPLATE(ALshort, 4, point16)
DECL_TEMPLATE(ALshort, 4, lerp16)
DECL_TEMPLATE(ALshort, 4, cubic16)
DECL_TEMPLATE(ALubyte, 4, point8)
DECL_TEMPLATE(ALubyte, 4, lerp8)
DECL_TEMPLATE(ALubyte, 4, cubic8)
DECL_TEMPLATE(ALfp, 6, point32)
DECL_TEMPLATE(ALfp, 6, lerp32)
DECL_TEMPLATE(ALfp, 6, cubic32)
DECL_TEMPLATE(ALshort, 6, point16)
DECL_TEMPLATE(ALshort, 6, lerp16)
DECL_TEMPLATE(ALshort, 6, cubic16)
DECL_TEMPLATE(ALubyte, 6, point8)
DECL_TEMPLATE(ALubyte, 6, lerp8)
DECL_TEMPLATE(ALubyte, 6, cubic8)
DECL_TEMPLATE(ALfp, 7, point32)
DECL_TEMPLATE(ALfp, 7, lerp32)
DECL_TEMPLATE(ALfp, 7, cubic32)
DECL_TEMPLATE(ALshort, 7, point16)
DECL_TEMPLATE(ALshort, 7, lerp16)
DECL_TEMPLATE(ALshort, 7, cubic16)
DECL_TEMPLATE(ALubyte, 7, point8)
DECL_TEMPLATE(ALubyte, 7, lerp8)
DECL_TEMPLATE(ALubyte, 7, cubic8)
DECL_TEMPLATE(ALfp, 8, point32)
DECL_TEMPLATE(ALfp, 8, lerp32)
DECL_TEMPLATE(ALfp, 8, cubic32)
DECL_TEMPLATE(ALshort, 8, point16)
DECL_TEMPLATE(ALshort, 8, lerp16)
DECL_TEMPLATE(ALshort, 8, cubic16)
DECL_TEMPLATE(ALubyte, 8, point8)
DECL_TEMPLATE(ALubyte, 8, lerp8)
DECL_TEMPLATE(ALubyte, 8, cubic8)
#undef DECL_TEMPLATE
#define DECL_TEMPLATE(T, sampler) \
static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
enum FmtChannels FmtChannels, \
const ALvoid *Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
switch(FmtChannels) \
{ \
case FmtMono: \
Mix_##T##_1_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
case FmtStereo: \
case FmtRear: \
Mix_##T##_2_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
case FmtQuad: \
Mix_##T##_4_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
case FmtX51: \
Mix_##T##_6_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
case FmtX61: \
Mix_##T##_7_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
case FmtX71: \
Mix_##T##_8_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
} \
}
DECL_TEMPLATE(ALfp, point32)
DECL_TEMPLATE(ALfp, lerp32)
DECL_TEMPLATE(ALfp, cubic32)
DECL_TEMPLATE(ALshort, point16)
DECL_TEMPLATE(ALshort, lerp16)
DECL_TEMPLATE(ALshort, cubic16)
DECL_TEMPLATE(ALubyte, point8)
DECL_TEMPLATE(ALubyte, lerp8)
DECL_TEMPLATE(ALubyte, cubic8)
#undef DECL_TEMPLATE
#define DECL_TEMPLATE(sampler) \
static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \
enum FmtChannels FmtChannels, enum FmtType FmtType, \
const ALvoid *Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
switch(FmtType) \
{ \
case FmtUByte: \
Mix_ALubyte_##sampler##8(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
\
case FmtShort: \
Mix_ALshort_##sampler##16(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
\
case FmtFloat: \
Mix_ALfp_##sampler##32(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
break; \
} \
}
DECL_TEMPLATE(point)
DECL_TEMPLATE(lerp)
DECL_TEMPLATE(cubic)
#undef DECL_TEMPLATE
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
{
ALbufferlistitem *BufferListItem;
ALuint DataPosInt, DataPosFrac;
enum FmtChannels FmtChannels;
enum FmtType FmtType;
ALuint BuffersPlayed;
ALboolean Looping;
ALuint increment;
resampler_t Resampler;
ALenum State;
ALuint OutPos;
ALuint FrameSize;
ALint64 DataSize64;
ALuint i;
/* Get source info */
State = Source->state;
BuffersPlayed = Source->BuffersPlayed;
DataPosInt = Source->position;
DataPosFrac = Source->position_fraction;
Looping = Source->bLooping;
increment = Source->Params.Step;
Resampler = (increment == FRACTIONONE) ? POINT_RESAMPLER :
Source->Resampler;
/* Get buffer info */
FrameSize = 0;
FmtChannels = FmtMono;
FmtType = FmtUByte;
BufferListItem = Source->queue;
for(i = 0;i < Source->BuffersInQueue;i++)
{
const ALbuffer *ALBuffer;
if((ALBuffer=BufferListItem->buffer) != NULL)
{
FmtChannels = ALBuffer->FmtChannels;
FmtType = ALBuffer->FmtType;
FrameSize = FrameSizeFromFmt(FmtChannels, FmtType);
break;
}
BufferListItem = BufferListItem->next;
}
/* Get current buffer queue item */
BufferListItem = Source->queue;
for(i = 0;i < BuffersPlayed;i++)
BufferListItem = BufferListItem->next;
OutPos = 0;
do {
const ALuint BufferPrePadding = ResamplerPrePadding[Resampler];
const ALuint BufferPadding = ResamplerPadding[Resampler];
ALubyte StackData[STACK_DATA_SIZE];
ALubyte *SrcData = StackData;
ALuint SrcDataSize = 0;
ALuint BufferSize;
/* Figure out how many buffer bytes will be needed */
DataSize64 = SamplesToDo-OutPos+1;
DataSize64 *= increment;
DataSize64 += DataPosFrac+FRACTIONMASK;
DataSize64 >>= FRACTIONBITS;
DataSize64 += BufferPadding+BufferPrePadding;
DataSize64 *= FrameSize;
BufferSize = min(DataSize64, STACK_DATA_SIZE);
BufferSize -= BufferSize%FrameSize;
if(Source->lSourceType == AL_STATIC)
{
const ALbuffer *ALBuffer = Source->Buffer;
const ALubyte *Data = ALBuffer->data;
ALuint DataSize;
ALuint pos;
/* If current pos is beyond the loop range, do not loop */
if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
{
Looping = AL_FALSE;
if(DataPosInt >= BufferPrePadding)
pos = (DataPosInt-BufferPrePadding)*FrameSize;
else
{
DataSize = (BufferPrePadding-DataPosInt)*FrameSize;
DataSize = min(BufferSize, DataSize);
memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
pos = 0;
}
/* Copy what's left to play in the source buffer, and clear the
* rest of the temp buffer */
DataSize = ALBuffer->size - pos;
DataSize = min(BufferSize, DataSize);
memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, BufferSize);
SrcDataSize += BufferSize;
BufferSize -= BufferSize;
}
else
{
ALuint LoopStart = ALBuffer->LoopStart;
ALuint LoopEnd = ALBuffer->LoopEnd;
if(DataPosInt >= LoopStart)
{
pos = DataPosInt-LoopStart;
while(pos < BufferPrePadding)
pos += LoopEnd-LoopStart;
pos -= BufferPrePadding;
pos += LoopStart;
pos *= FrameSize;
}
else if(DataPosInt >= BufferPrePadding)
pos = (DataPosInt-BufferPrePadding)*FrameSize;
else
{
DataSize = (BufferPrePadding-DataPosInt)*FrameSize;
DataSize = min(BufferSize, DataSize);
memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
pos = 0;
}
/* Copy what's left of this loop iteration, then copy repeats
* of the loop section */
DataSize = LoopEnd*FrameSize - pos;
DataSize = min(BufferSize, DataSize);
memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
DataSize = (LoopEnd-LoopStart) * FrameSize;
while(BufferSize > 0)
{
DataSize = min(BufferSize, DataSize);
memcpy(&SrcData[SrcDataSize], &Data[LoopStart*FrameSize], DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
}
}
}
else
{
/* Crawl the buffer queue to fill in the temp buffer */
ALbufferlistitem *BufferListIter = BufferListItem;
ALuint pos;
if(DataPosInt >= BufferPrePadding)
pos = (DataPosInt-BufferPrePadding)*FrameSize;
else
{
pos = (BufferPrePadding-DataPosInt)*FrameSize;
while(pos > 0)
{
if(!BufferListIter->prev && !Looping)
{
ALuint DataSize = min(BufferSize, pos);
memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
pos = 0;
break;
}
if(BufferListIter->prev)
BufferListIter = BufferListIter->prev;
else
{
while(BufferListIter->next)
BufferListIter = BufferListIter->next;
}
if(BufferListIter->buffer)
{
if((ALuint)BufferListIter->buffer->size > pos)
{
pos = BufferListIter->buffer->size - pos;
break;
}
pos -= BufferListIter->buffer->size;
}
}
}
while(BufferListIter && BufferSize > 0)
{
const ALbuffer *ALBuffer;
if((ALBuffer=BufferListIter->buffer) != NULL)
{
const ALubyte *Data = ALBuffer->data;
ALuint DataSize = ALBuffer->size;
/* Skip the data already played */
if(DataSize <= pos)
pos -= DataSize;
else
{
Data += pos;
DataSize -= pos;
pos -= pos;
DataSize = min(BufferSize, DataSize);
memcpy(&SrcData[SrcDataSize], Data, DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
}
}
BufferListIter = BufferListIter->next;
if(!BufferListIter && Looping)
BufferListIter = Source->queue;
else if(!BufferListIter)
{
memset(&SrcData[SrcDataSize], (FmtType==FmtUByte)?0x80:0, BufferSize);
SrcDataSize += BufferSize;
BufferSize -= BufferSize;
}
}
}
/* Figure out how many samples we can mix. */
DataSize64 = SrcDataSize / FrameSize;
DataSize64 -= BufferPadding+BufferPrePadding;
DataSize64 <<= FRACTIONBITS;
DataSize64 -= increment;
DataSize64 -= DataPosFrac;
BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
BufferSize = min(BufferSize, (SamplesToDo-OutPos));
SrcData += BufferPrePadding*FrameSize;
switch(Resampler)
{
case POINT_RESAMPLER:
Mix_point(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case LINEAR_RESAMPLER:
Mix_lerp(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case CUBIC_RESAMPLER:
Mix_cubic(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case RESAMPLER_MIN:
case RESAMPLER_MAX:
break;
}
OutPos += BufferSize;
/* Handle looping sources */
while(1)
{
const ALbuffer *ALBuffer;
ALuint DataSize = 0;
ALuint LoopStart = 0;
ALuint LoopEnd = 0;
if((ALBuffer=BufferListItem->buffer) != NULL)
{
DataSize = ALBuffer->size / FrameSize;
LoopStart = ALBuffer->LoopStart;
LoopEnd = ALBuffer->LoopEnd;
if(LoopEnd > DataPosInt)
break;
}
if(Looping && Source->lSourceType == AL_STATIC)
{
BufferListItem = Source->queue;
DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
break;
}
if(DataSize > DataPosInt)
break;
if(BufferListItem->next)
{
BufferListItem = BufferListItem->next;
BuffersPlayed++;
}
else if(Looping)
{
BufferListItem = Source->queue;
BuffersPlayed = 0;
}
else
{
State = AL_STOPPED;
BufferListItem = Source->queue;
BuffersPlayed = Source->BuffersInQueue;
DataPosInt = 0;
DataPosFrac = 0;
break;
}
DataPosInt -= DataSize;
}
} while(State == AL_PLAYING && OutPos < SamplesToDo);
/* Update source info */
Source->state = State;
Source->BuffersPlayed = BuffersPlayed;
Source->position = DataPosInt;
Source->position_fraction = DataPosFrac;
Source->Buffer = BufferListItem->buffer;
}

182
jni/OpenAL/Alc/null.c Normal file
View File

@ -0,0 +1,182 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 2010 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 <stdlib.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
typedef struct {
ALvoid *buffer;
ALuint size;
volatile int killNow;
ALvoid *thread;
} null_data;
static const ALCchar nullDevice[] = "No Output";
static ALuint NullProc(ALvoid *ptr)
{
ALCdevice *Device = (ALCdevice*)ptr;
null_data *data = (null_data*)Device->ExtraData;
ALuint now, start;
ALuint64 avail, done;
const ALuint restTime = ((ALuint)((ALuint64)Device->UpdateSize * 1000 /
Device->Frequency)) / 2;
done = 0;
start = timeGetTime();
while(!data->killNow && Device->Connected)
{
now = timeGetTime();
avail = (ALuint64)(now-start) * Device->Frequency / 1000;
if(avail < done)
{
/* Timer wrapped. Add the remainder of the cycle to the available
* count and reset the number of samples done */
avail += (ALuint64)0xFFFFFFFFu*Device->Frequency/1000 - done;
done = 0;
}
if(avail-done < Device->UpdateSize)
{
Sleep(restTime);
continue;
}
while(avail-done >= Device->UpdateSize)
{
aluMixData(Device, data->buffer, Device->UpdateSize);
done += Device->UpdateSize;
}
}
return 0;
}
static ALCboolean null_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
null_data *data;
if(!deviceName)
deviceName = nullDevice;
else if(strcmp(deviceName, nullDevice) != 0)
return ALC_FALSE;
data = (null_data*)calloc(1, sizeof(*data));
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
static void null_close_playback(ALCdevice *device)
{
null_data *data = (null_data*)device->ExtraData;
free(data);
device->ExtraData = NULL;
}
static ALCboolean null_reset_playback(ALCdevice *device)
{
null_data *data = (null_data*)device->ExtraData;
data->size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans,
device->FmtType);
data->buffer = malloc(data->size);
if(!data->buffer)
{
AL_PRINT("buffer malloc failed\n");
return ALC_FALSE;
}
SetDefaultWFXChannelOrder(device);
data->thread = StartThread(NullProc, device);
if(data->thread == NULL)
{
free(data->buffer);
data->buffer = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void null_stop_playback(ALCdevice *device)
{
null_data *data = (null_data*)device->ExtraData;
if(!data->thread)
return;
data->killNow = 1;
StopThread(data->thread);
data->thread = NULL;
data->killNow = 0;
free(data->buffer);
data->buffer = NULL;
}
static ALCboolean null_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
(void)device;
(void)deviceName;
return ALC_FALSE;
}
BackendFuncs null_funcs = {
null_open_playback,
null_close_playback,
null_reset_playback,
null_stop_playback,
null_open_capture,
NULL,
NULL,
NULL,
NULL,
NULL
};
void alc_null_init(BackendFuncs *func_list)
{
*func_list = null_funcs;
}
void alc_null_deinit(void)
{
}
void alc_null_probe(int type)
{
if(type == DEVICE_PROBE)
AppendDeviceList(nullDevice);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(nullDevice);
}

411
jni/OpenAL/Alc/opensles.c Normal file
View File

@ -0,0 +1,411 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* This is an OpenAL backend for Android using the native audio APIs based on OpenSL ES 1.0.1.
* It is based on source code for the native-audio sample app bundled with NDK.
*/
#include <stdlib.h>
#include <time.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "verde/verde_helpers.h"
#define LOG_NDEBUG 0
#define LOG_TAG "OpenAL"
// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
#if 1
#define LOGV(...) VERDE_DEBUG(__VA_ARGS__)
#endif
// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
#include "apportable_openal_funcs.h"
// engine interfaces
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;
// output mix interfaces
static SLObjectItf outputMixObject = NULL;
// buffer queue player interfaces
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
// this callback handler is called every time a buffer finishes playing
static void opensles_callback(SLAndroidSimpleBufferQueueItf bq, void *context)
{
// LOGV("opensles_callback");
#define bufferSize (1024*4)
static char buffer0[bufferSize], buffer1[bufferSize];
static char * const buffers[2] = {buffer0, buffer1};
static unsigned bufferIndex = 0;
#if 0
static unsigned nextCount = ~0;
static char nextBuffer[1024] = "Hello, world!";
static unsigned nextSize = 1024;
#endif
assert(bq == bqPlayerBufferQueue);
assert(NULL != context);
ALCdevice *pDevice = (ALCdevice *) context;
ALint frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
void *buffer = buffers[bufferIndex];
// LOGV("bq=%p, pDevice=%p, frameSize=%u, buffer=%p, bufferIndex=%u, bufferSize=%u", bq, pDevice, frameSize, buffer, bufferIndex, bufferSize);
bufferIndex ^= 1;
// LOGV("aluMixData");
aluMixData(pDevice, buffer, bufferSize/frameSize);
// LOGV("Enqueue2");
#if 0
// for streaming playback, replace this test by logic to find and fill the next buffer
if (--nextCount > 0 && NULL != nextBuffer && 0 != nextSize) {
SLresult result;
// enqueue another buffer
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
// the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
// which for this code example would indicate a programming error
assert(SL_RESULT_SUCCESS == result);
}
#else
SLresult result;
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer, bufferSize);
assert(SL_RESULT_SUCCESS == result);
#endif
}
static const ALCchar opensles_device[] = "OpenSL ES";
// Apportable extensions
SLEngineItf alc_opensles_get_native_audio_engine_engine()
{
return engineEngine;
}
SLEngineItf alc_opensles_get_native_audio_output_mix()
{
return outputMixObject;
}
SLresult alc_opensles_create_native_audio_engine()
{
if (engineObject)
return SL_RESULT_SUCCESS;
SLresult result;
// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
assert(SL_RESULT_SUCCESS == result);
// create output mix
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
return result;
}
// Backend functions, in same order as type BackendFuncs
static ALCboolean opensles_open_playback(ALCdevice *pDevice, const ALCchar *deviceName)
{
LOGV("opensles_open_playback pDevice=%p, deviceName=%s", pDevice, deviceName);
// create the engine and output mix objects
SLresult result = alc_opensles_create_native_audio_engine();
// create buffer queue audio player
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 2, SL_SAMPLINGRATE_44_1,
SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT, SL_BYTEORDER_LITTLEENDIAN};
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
SLDataSink audioSnk = {&loc_outmix, NULL};
// create audio player
LOGV("create audio player");
const SLInterfaceID ids[1] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk,
1, ids, req);
assert(SL_RESULT_SUCCESS == result);
// realize the player
result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
// get the play interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
// get the buffer queue interface
result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
&bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
// register callback on the buffer queue
result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, opensles_callback, (void *) pDevice);
assert(SL_RESULT_SUCCESS == result);
// set the player's state to playing
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
// enqueue the first buffer to kick off the callbacks
LOGV("enqueue");
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, "\0", 1);
assert(SL_RESULT_SUCCESS == result);
return ALC_TRUE;
}
static void opensles_close_playback(ALCdevice *pDevice)
{
LOGV("opensles_close_playback pDevice=%p", pDevice);
// shut down the native audio system
// destroy buffer queue audio player object, and invalidate all associated interfaces
if (bqPlayerObject != NULL) {
(*bqPlayerObject)->Destroy(bqPlayerObject);
bqPlayerObject = NULL;
bqPlayerPlay = NULL;
bqPlayerBufferQueue = NULL;
}
// destroy output mix object, and invalidate all associated interfaces
if (outputMixObject != NULL) {
(*outputMixObject)->Destroy(outputMixObject);
outputMixObject = NULL;
}
// destroy engine object, and invalidate all associated interfaces
if (engineObject != NULL) {
(*engineObject)->Destroy(engineObject);
engineObject = NULL;
engineEngine = NULL;
}
}
static ALCboolean opensles_reset_playback(ALCdevice *pDevice)
{
LOGV("opensles_reset_playback pDevice=%p", pDevice);
unsigned bits = BytesFromDevFmt(pDevice->FmtType) * 8;
unsigned channels = ChannelsFromDevFmt(pDevice->FmtChans);
unsigned samples = pDevice->UpdateSize;
unsigned size = samples * channels * bits / 8;
LOGV("bits=%u, channels=%u, samples=%u, size=%u, freq=%u", bits, channels, samples, size, pDevice->Frequency);
SetDefaultWFXChannelOrder(pDevice);
#if 0
if (pSDL_WasInit(SDL_INIT_AUDIO))
{
pSDL_PauseAudio(1);
pSDL_CloseAudio();
pSDL_QuitSubSystem(SDL_INIT_AUDIO);
}
switch (aluBytesFromFormat(device->Format))
{
case 1:
desired.format = AUDIO_U8;
break;
case 4:
switch (ChannelsFromDevFormat(device->DevFmt))
{
case 1: device->Format = AL_FORMAT_MONO16; break;
case 2: device->Format = AL_FORMAT_STEREO16; break;
case 4: device->Format = AL_FORMAT_QUAD16; break;
case 6: device->Format = AL_FORMAT_51CHN16; break;
case 7: device->Format = AL_FORMAT_61CHN16; break;
case 8: device->Format = AL_FORMAT_71CHN16; break;
}
/* fall-through */
case 2:
desired.format = AUDIO_S16;
break;
default:
AL_PRINT("Unknown format: 0x%x\n", device->Format);
return ALC_FALSE;
}
desired.freq = device->Frequency;
desired.channels = aluChannelsFromFormat(device->Format);
desired.samples = device->UpdateSize * desired.channels;
desired.callback = opensles_callback;
desired.userdata = device;
device->NumUpdates = 2;
if (pSDL_InitSubSystem(SDL_INIT_AUDIO) == -1)
{
AL_PRINT("SDL_InitSubSystem(SDL_INIT_AUDIO) failed: %s\n", pSDL_GetError());
return ALC_FALSE;
}
if (pSDL_OpenAudio(&desired, NULL) == -1)
{
AL_PRINT("SDL_OpenAudio failed: %s\n", pSDL_GetError());
pSDL_QuitSubSystem(SDL_INIT_AUDIO);
return ALC_FALSE;
}
pSDL_PauseAudio(0);
#endif
return ALC_TRUE;
}
static void opensles_stop_playback(ALCdevice *pDevice)
{
LOGV("opensles_stop_playback device=%p", pDevice);
}
static ALCboolean opensles_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
{
LOGV("opensles_open_capture device=%p, deviceName=%s", pDevice, deviceName);
return ALC_FALSE;
}
static void opensles_close_capture(ALCdevice *pDevice)
{
LOGV("opensles_closed_capture device=%p", pDevice);
}
static void opensles_start_capture(ALCdevice *pDevice)
{
LOGV("opensles_start_capture device=%p", pDevice);
}
static void opensles_stop_capture(ALCdevice *pDevice)
{
LOGV("opensles_stop_capture device=%p", pDevice);
}
static void opensles_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
LOGV("opensles_capture_samples device=%p, pBuffer=%p, lSamples=%u", pDevice, pBuffer, lSamples);
}
static ALCuint opensles_available_samples(ALCdevice *pDevice)
{
LOGV("opensles_available_samples device=%p", pDevice);
return 0;
}
// table of backend function pointers
BackendFuncs opensles_funcs = {
opensles_open_playback,
opensles_close_playback,
opensles_reset_playback,
opensles_stop_playback,
opensles_open_capture,
opensles_close_capture,
opensles_start_capture,
opensles_stop_capture,
opensles_capture_samples,
opensles_available_samples
};
// global entry points called from XYZZY
void alc_opensles_suspend()
{
SLresult result;
if (bqPlayerPlay) {
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PAUSED);
assert(SL_RESULT_SUCCESS == result);
result = (*bqPlayerBufferQueue)->Clear(bqPlayerBufferQueue);
assert(SL_RESULT_SUCCESS == result);
}
}
void alc_opensles_resume()
{
SLresult result;
if (bqPlayerPlay) {
result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
assert(SL_RESULT_SUCCESS == result);
// Pump some blank data into the buffer to stimulate the callback
result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, "\0", 1);
assert(SL_RESULT_SUCCESS == result);
}
}
void alc_opensles_init(BackendFuncs *func_list)
{
LOGV("alc_opensles_init");
*func_list = opensles_funcs;
apportableOpenALFuncs.alc_android_suspend = alc_opensles_suspend;
apportableOpenALFuncs.alc_android_resume = alc_opensles_resume;
apportableOpenALFuncs.alc_opensles_get_native_audio_engine_engine = alc_opensles_get_native_audio_engine_engine;
apportableOpenALFuncs.alc_opensles_get_native_audio_output_mix = alc_opensles_get_native_audio_output_mix;
apportableOpenALFuncs.alc_opensles_create_native_audio_engine = alc_opensles_create_native_audio_engine;
}
void alc_opensles_deinit(void)
{
LOGV("alc_opensles_deinit");
}
void alc_opensles_probe(int type)
{
switch (type) {
case DEVICE_PROBE:
LOGV("alc_opensles_probe DEVICE_PROBE");
AppendDeviceList(opensles_device);
break;
case ALL_DEVICE_PROBE:
LOGV("alc_opensles_probe ALL_DEVICE_PROBE");
AppendAllDeviceList(opensles_device);
break;
default:
LOGV("alc_opensles_probe type=%d", type);
break;
}
}

521
jni/OpenAL/Alc/oss.c Normal file
View File

@ -0,0 +1,521 @@
/**
* 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 <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include <sys/soundcard.h>
/*
* The OSS documentation talks about SOUND_MIXER_READ, but the header
* only contains MIXER_READ. Play safe. Same for WRITE.
*/
#ifndef SOUND_MIXER_READ
#define SOUND_MIXER_READ MIXER_READ
#endif
#ifndef SOUND_MIXER_WRITE
#define SOUND_MIXER_WRITE MIXER_WRITE
#endif
static const ALCchar oss_device[] = "OSS Default";
typedef struct {
int fd;
volatile int killNow;
ALvoid *thread;
ALubyte *mix_data;
int data_size;
RingBuffer *ring;
int doCapture;
} oss_data;
static int log2i(ALCuint x)
{
int y = 0;
while (x > 1)
{
x >>= 1;
y++;
}
return y;
}
static ALuint OSSProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
oss_data *data = (oss_data*)pDevice->ExtraData;
ALint frameSize;
ssize_t wrote;
SetRTPriority();
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
while(!data->killNow && pDevice->Connected)
{
ALint len = data->data_size;
ALubyte *WritePtr = data->mix_data;
aluMixData(pDevice, WritePtr, len/frameSize);
while(len > 0 && !data->killNow)
{
wrote = write(data->fd, WritePtr, len);
if(wrote < 0)
{
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
AL_PRINT("write failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
Sleep(1);
continue;
}
len -= wrote;
WritePtr += wrote;
}
}
return 0;
}
static ALuint OSSCaptureProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
oss_data *data = (oss_data*)pDevice->ExtraData;
int frameSize;
int amt;
SetRTPriority();
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
while(!data->killNow)
{
amt = read(data->fd, data->mix_data, data->data_size);
if(amt < 0)
{
AL_PRINT("read failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
if(amt == 0)
{
Sleep(1);
continue;
}
if(data->doCapture)
WriteRingBuffer(data->ring, data->mix_data, amt/frameSize);
}
return 0;
}
static ALCboolean oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
char driver[64];
oss_data *data;
strncpy(driver, GetConfigValue("oss", "device", "/dev/dsp"), sizeof(driver)-1);
driver[sizeof(driver)-1] = 0;
if(!deviceName)
deviceName = oss_device;
else if(strcmp(deviceName, oss_device) != 0)
return ALC_FALSE;
data = (oss_data*)calloc(1, sizeof(oss_data));
data->killNow = 0;
data->fd = open(driver, O_WRONLY);
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
static void oss_close_playback(ALCdevice *device)
{
oss_data *data = (oss_data*)device->ExtraData;
close(data->fd);
free(data);
device->ExtraData = NULL;
}
static ALCboolean oss_reset_playback(ALCdevice *device)
{
oss_data *data = (oss_data*)device->ExtraData;
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
int numChannels;
int ossFormat;
int ossSpeed;
char *err;
switch(device->FmtType)
{
case DevFmtByte:
ossFormat = AFMT_S8;
break;
case DevFmtUByte:
ossFormat = AFMT_U8;
break;
case DevFmtUShort:
case DevFmtFloat:
device->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
ossFormat = AFMT_S16_NE;
break;
}
periods = device->NumUpdates;
numChannels = ChannelsFromDevFmt(device->FmtChans);
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
ossSpeed = device->Frequency;
log2FragmentSize = log2i(device->UpdateSize * frameSize);
/* according to the OSS spec, 16 bytes are the minimum */
if (log2FragmentSize < 4)
log2FragmentSize = 4;
/* Subtract one period since the temp mixing buffer counts as one. Still
* need at least two on the card, though. */
if(periods > 2) periods--;
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
#define CHECKERR(func) if((func) < 0) { \
err = #func; \
goto err; \
}
/* Don't fail if SETFRAGMENT fails. We can handle just about anything
* that's reported back via GETOSPACE */
ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize);
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETOSPACE, &info));
if(0)
{
err:
AL_PRINT("%s failed: %s\n", err, strerror(errno));
return ALC_FALSE;
}
#undef CHECKERR
if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), numChannels);
return ALC_FALSE;
}
if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
(ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
(ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
{
AL_PRINT("Could not set %#x format type, got OSS format %#x\n", device->FmtType, ossFormat);
return ALC_FALSE;
}
device->Frequency = ossSpeed;
device->UpdateSize = info.fragsize / frameSize;
device->NumUpdates = info.fragments + 1;
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
SetDefaultChannelOrder(device);
data->thread = StartThread(OSSProc, device);
if(data->thread == NULL)
{
free(data->mix_data);
data->mix_data = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void oss_stop_playback(ALCdevice *device)
{
oss_data *data = (oss_data*)device->ExtraData;
if(!data->thread)
return;
data->killNow = 1;
StopThread(data->thread);
data->thread = NULL;
data->killNow = 0;
if(ioctl(data->fd, SNDCTL_DSP_RESET) != 0)
AL_PRINT("Error resetting device: %s\n", strerror(errno));
free(data->mix_data);
data->mix_data = NULL;
}
static ALCboolean oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
int numFragmentsLogSize;
int log2FragmentSize;
unsigned int periods;
audio_buf_info info;
ALuint frameSize;
int numChannels;
char driver[64];
oss_data *data;
int ossFormat;
int ossSpeed;
char *err;
strncpy(driver, GetConfigValue("oss", "capture", "/dev/dsp"), sizeof(driver)-1);
driver[sizeof(driver)-1] = 0;
if(!deviceName)
deviceName = oss_device;
else if(strcmp(deviceName, oss_device) != 0)
return ALC_FALSE;
data = (oss_data*)calloc(1, sizeof(oss_data));
data->killNow = 0;
data->fd = open(driver, O_RDONLY);
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
switch(device->FmtType)
{
case DevFmtByte:
ossFormat = AFMT_S8;
break;
case DevFmtUByte:
ossFormat = AFMT_U8;
break;
case DevFmtShort:
ossFormat = AFMT_S16_NE;
break;
case DevFmtUShort:
case DevFmtFloat:
free(data);
AL_PRINT("Format type %#x capture not supported on OSS\n", device->FmtType);
return ALC_FALSE;
}
periods = 4;
numChannels = ChannelsFromDevFmt(device->FmtChans);
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
ossSpeed = device->Frequency;
log2FragmentSize = log2i(device->UpdateSize * device->NumUpdates *
frameSize / periods);
/* according to the OSS spec, 16 bytes are the minimum */
if (log2FragmentSize < 4)
log2FragmentSize = 4;
numFragmentsLogSize = (periods << 16) | log2FragmentSize;
#define CHECKERR(func) if((func) < 0) { \
err = #func; \
goto err; \
}
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFRAGMENT, &numFragmentsLogSize));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SETFMT, &ossFormat));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_CHANNELS, &numChannels));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_SPEED, &ossSpeed));
CHECKERR(ioctl(data->fd, SNDCTL_DSP_GETISPACE, &info));
if(0)
{
err:
AL_PRINT("%s failed: %s\n", err, strerror(errno));
close(data->fd);
free(data);
return ALC_FALSE;
}
#undef CHECKERR
if((int)ChannelsFromDevFmt(device->FmtChans) != numChannels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), numChannels);
close(data->fd);
free(data);
return ALC_FALSE;
}
if(!((ossFormat == AFMT_S8 && device->FmtType == DevFmtByte) ||
(ossFormat == AFMT_U8 && device->FmtType == DevFmtUByte) ||
(ossFormat == AFMT_S16_NE && device->FmtType == DevFmtShort)))
{
AL_PRINT("Could not set %#x format type, got OSS format %#x\n", device->FmtType, ossFormat);
close(data->fd);
free(data);
return ALC_FALSE;
}
data->ring = CreateRingBuffer(frameSize, device->UpdateSize * device->NumUpdates);
if(!data->ring)
{
AL_PRINT("ring buffer create failed\n");
close(data->fd);
free(data);
return ALC_FALSE;
}
data->data_size = info.fragsize;
data->mix_data = calloc(1, data->data_size);
device->ExtraData = data;
data->thread = StartThread(OSSCaptureProc, device);
if(data->thread == NULL)
{
device->ExtraData = NULL;
free(data->mix_data);
free(data);
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
return ALC_TRUE;
}
static void oss_close_capture(ALCdevice *device)
{
oss_data *data = (oss_data*)device->ExtraData;
data->killNow = 1;
StopThread(data->thread);
close(data->fd);
DestroyRingBuffer(data->ring);
free(data->mix_data);
free(data);
device->ExtraData = NULL;
}
static void oss_start_capture(ALCdevice *pDevice)
{
oss_data *data = (oss_data*)pDevice->ExtraData;
data->doCapture = 1;
}
static void oss_stop_capture(ALCdevice *pDevice)
{
oss_data *data = (oss_data*)pDevice->ExtraData;
data->doCapture = 0;
}
static void oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
oss_data *data = (oss_data*)pDevice->ExtraData;
if(lSamples <= (ALCuint)RingBufferSize(data->ring))
ReadRingBuffer(data->ring, pBuffer, lSamples);
else
alcSetError(pDevice, ALC_INVALID_VALUE);
}
static ALCuint oss_available_samples(ALCdevice *pDevice)
{
oss_data *data = (oss_data*)pDevice->ExtraData;
return RingBufferSize(data->ring);
}
BackendFuncs oss_funcs = {
oss_open_playback,
oss_close_playback,
oss_reset_playback,
oss_stop_playback,
oss_open_capture,
oss_close_capture,
oss_start_capture,
oss_stop_capture,
oss_capture_samples,
oss_available_samples
};
void alc_oss_init(BackendFuncs *func_list)
{
*func_list = oss_funcs;
}
void alc_oss_deinit(void)
{
}
void alc_oss_probe(int type)
{
if(type == DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0)
#endif
AppendDeviceList(oss_device);
}
else if(type == ALL_DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "device", "/dev/dsp"), &buf) == 0)
#endif
AppendAllDeviceList(oss_device);
}
else if(type == CAPTURE_DEVICE_PROBE)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("oss", "capture", "/dev/dsp"), &buf) == 0)
#endif
AppendCaptureDeviceList(oss_device);
}
}

364
jni/OpenAL/Alc/panning.c Normal file
View File

@ -0,0 +1,364 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2010 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 <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "alu.h"
static void SetSpeakerArrangement(const char *name, ALfp SpeakerAngle[MAXCHANNELS],
Channel Speaker2Chan[MAXCHANNELS], ALint chans)
{
char layout_str[256];
char *confkey, *next;
char *sep, *end;
Channel val;
int i;
if(!ConfigValueExists(NULL, name))
name = "layout";
strncpy(layout_str, GetConfigValue(NULL, name, ""), sizeof(layout_str));
layout_str[sizeof(layout_str)-1] = 0;
if(!layout_str[0])
return;
next = confkey = layout_str;
while(next && *next)
{
confkey = next;
next = strchr(confkey, ',');
if(next)
{
*next = 0;
do {
next++;
} while(isspace(*next) || *next == ',');
}
sep = strchr(confkey, '=');
if(!sep || confkey == sep)
continue;
end = sep - 1;
while(isspace(*end) && end != confkey)
end--;
*(++end) = 0;
if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0)
val = FRONT_LEFT;
else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0)
val = FRONT_RIGHT;
else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0)
val = FRONT_CENTER;
else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0)
val = BACK_LEFT;
else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0)
val = BACK_RIGHT;
else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0)
val = BACK_CENTER;
else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0)
val = SIDE_LEFT;
else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0)
val = SIDE_RIGHT;
else
{
AL_PRINT("Unknown speaker for %s: \"%s\"\n", name, confkey);
continue;
}
*(sep++) = 0;
while(isspace(*sep))
sep++;
for(i = 0;i < chans;i++)
{
if(Speaker2Chan[i] == val)
{
long angle = strtol(sep, NULL, 10);
if(angle >= -180 && angle <= 180)
SpeakerAngle[i] = ALfpMult(int2ALfp(angle), float2ALfp(M_PI/180.0f));
else
AL_PRINT("Invalid angle for speaker \"%s\": %ld\n", confkey, angle);
break;
}
}
}
for(i = 0;i < chans;i++)
{
int min = i;
int i2;
for(i2 = i+1;i2 < chans;i2++)
{
if(SpeakerAngle[i2] < SpeakerAngle[min])
min = i2;
}
if(min != i)
{
ALfp tmpf;
Channel tmpc;
tmpf = SpeakerAngle[i];
SpeakerAngle[i] = SpeakerAngle[min];
SpeakerAngle[min] = tmpf;
tmpc = Speaker2Chan[i];
Speaker2Chan[i] = Speaker2Chan[min];
Speaker2Chan[min] = tmpc;
}
}
}
static ALfp aluLUTpos2Angle(ALint pos)
{
if(pos < QUADRANT_NUM)
return aluAtan(ALfpDiv(int2ALfp(pos), int2ALfp(QUADRANT_NUM - pos)));
if(pos < 2 * QUADRANT_NUM)
return (float2ALfp(M_PI_2) + aluAtan(ALfpDiv(int2ALfp(pos - QUADRANT_NUM),int2ALfp(2 * QUADRANT_NUM - pos))));
if(pos < 3 * QUADRANT_NUM)
return (aluAtan(ALfpDiv(int2ALfp(pos - 2 * QUADRANT_NUM), int2ALfp(3 * QUADRANT_NUM - pos))) - float2ALfp(M_PI));
return (aluAtan(ALfpDiv(int2ALfp(pos - 3 * QUADRANT_NUM), int2ALfp(4 * QUADRANT_NUM - pos))) - float2ALfp(M_PI));
}
ALint aluCart2LUTpos(ALfp re, ALfp im)
{
ALint pos = 0;
ALfp denom = (aluFabs(re) + aluFabs(im));
if(denom > int2ALfp(0))
pos = (ALint)ALfp2int(ALfpDiv(ALfpMult(int2ALfp(QUADRANT_NUM),aluFabs(im)), (denom + float2ALfp(0.5))));
if(re < int2ALfp(0))
pos = 2 * QUADRANT_NUM - pos;
if(im < int2ALfp(0))
pos = LUT_NUM - pos;
return pos%LUT_NUM;
}
ALvoid aluInitPanning(ALCdevice *Device)
{
ALfp SpeakerAngle[MAXCHANNELS];
ALfp (*Matrix)[MAXCHANNELS];
Channel *Speaker2Chan;
ALfp Alpha, Theta;
ALfp *PanningLUT;
ALint pos, offset;
ALuint s, s2;
for(s = 0;s < MAXCHANNELS;s++)
{
for(s2 = 0;s2 < MAXCHANNELS;s2++)
Device->ChannelMatrix[s][s2] = ((s==s2) ? int2ALfp(1) : int2ALfp(0));
}
Speaker2Chan = Device->Speaker2Chan;
Matrix = Device->ChannelMatrix;
switch(Device->FmtChans)
{
case DevFmtMono:
Matrix[FRONT_LEFT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[FRONT_RIGHT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_LEFT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_RIGHT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_LEFT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_RIGHT][FRONT_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][FRONT_CENTER] = int2ALfp(1);
Device->NumChan = 1;
Speaker2Chan[0] = FRONT_CENTER;
SpeakerAngle[0] = int2ALfp(0);
break;
case DevFmtStereo:
#ifdef APPORTABLE_OPTIMIZED_OUT
// Leave as identity matrix if Apportable-optimized
Matrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_LEFT][FRONT_LEFT] = int2ALfp(1);
Matrix[SIDE_RIGHT][FRONT_RIGHT] = int2ALfp(1);
Matrix[BACK_LEFT][FRONT_LEFT] = int2ALfp(1);
Matrix[BACK_RIGHT][FRONT_RIGHT] = int2ALfp(1);
Matrix[BACK_CENTER][FRONT_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][FRONT_RIGHT] = aluSqrt(float2ALfp(0.5));
#endif
Device->NumChan = 2;
Speaker2Chan[0] = FRONT_LEFT;
Speaker2Chan[1] = FRONT_RIGHT;
SpeakerAngle[0] = float2ALfp(-90.0f * M_PI/180.0f);
SpeakerAngle[1] = float2ALfp( 90.0f * M_PI/180.0f);
SetSpeakerArrangement("layout_STEREO", SpeakerAngle, Speaker2Chan, Device->NumChan);
break;
case DevFmtQuad:
Matrix[FRONT_CENTER][FRONT_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[FRONT_CENTER][FRONT_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][BACK_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(float2ALfp(0.5));
Device->NumChan = 4;
Speaker2Chan[0] = BACK_LEFT;
Speaker2Chan[1] = FRONT_LEFT;
Speaker2Chan[2] = FRONT_RIGHT;
Speaker2Chan[3] = BACK_RIGHT;
SpeakerAngle[0] = float2ALfp(-135.0f * M_PI/180.0f);
SpeakerAngle[1] = float2ALfp( -45.0f * M_PI/180.0f);
SpeakerAngle[2] = float2ALfp( 45.0f * M_PI/180.0f);
SpeakerAngle[3] = float2ALfp( 135.0f * M_PI/180.0f);
SetSpeakerArrangement("layout_QUAD", SpeakerAngle, Speaker2Chan, Device->NumChan);
break;
case DevFmtX51:
Matrix[SIDE_LEFT][FRONT_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_LEFT][BACK_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_RIGHT][FRONT_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[SIDE_RIGHT][BACK_RIGHT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][BACK_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(float2ALfp(0.5));
Device->NumChan = 5;
Speaker2Chan[0] = BACK_LEFT;
Speaker2Chan[1] = FRONT_LEFT;
Speaker2Chan[2] = FRONT_CENTER;
Speaker2Chan[3] = FRONT_RIGHT;
Speaker2Chan[4] = BACK_RIGHT;
SpeakerAngle[0] = float2ALfp(-110.0f * M_PI/180.0f);
SpeakerAngle[1] = float2ALfp( -30.0f * M_PI/180.0f);
SpeakerAngle[2] = float2ALfp( 0.0f * M_PI/180.0f);
SpeakerAngle[3] = float2ALfp( 30.0f * M_PI/180.0f);
SpeakerAngle[4] = float2ALfp( 110.0f * M_PI/180.0f);
SetSpeakerArrangement("layout_51CHN", SpeakerAngle, Speaker2Chan, Device->NumChan);
break;
case DevFmtX61:
Matrix[BACK_LEFT][BACK_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_LEFT][SIDE_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_RIGHT][BACK_CENTER] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_RIGHT][SIDE_RIGHT] = aluSqrt(float2ALfp(0.5));
Device->NumChan = 6;
Speaker2Chan[0] = SIDE_LEFT;
Speaker2Chan[1] = FRONT_LEFT;
Speaker2Chan[2] = FRONT_CENTER;
Speaker2Chan[3] = FRONT_RIGHT;
Speaker2Chan[4] = SIDE_RIGHT;
Speaker2Chan[5] = BACK_CENTER;
SpeakerAngle[0] = float2ALfp(-90.0f * M_PI/180.0f);
SpeakerAngle[1] = float2ALfp(-30.0f * M_PI/180.0f);
SpeakerAngle[2] = float2ALfp( 0.0f * M_PI/180.0f);
SpeakerAngle[3] = float2ALfp( 30.0f * M_PI/180.0f);
SpeakerAngle[4] = float2ALfp( 90.0f * M_PI/180.0f);
SpeakerAngle[5] = float2ALfp(180.0f * M_PI/180.0f);
SetSpeakerArrangement("layout_61CHN", SpeakerAngle, Speaker2Chan, Device->NumChan);
break;
case DevFmtX71:
Matrix[BACK_CENTER][BACK_LEFT] = aluSqrt(float2ALfp(0.5));
Matrix[BACK_CENTER][BACK_RIGHT] = aluSqrt(float2ALfp(0.5));
Device->NumChan = 7;
Speaker2Chan[0] = BACK_LEFT;
Speaker2Chan[1] = SIDE_LEFT;
Speaker2Chan[2] = FRONT_LEFT;
Speaker2Chan[3] = FRONT_CENTER;
Speaker2Chan[4] = FRONT_RIGHT;
Speaker2Chan[5] = SIDE_RIGHT;
Speaker2Chan[6] = BACK_RIGHT;
SpeakerAngle[0] = float2ALfp(-150.0f * M_PI/180.0f);
SpeakerAngle[1] = float2ALfp( -90.0f * M_PI/180.0f);
SpeakerAngle[2] = float2ALfp( -30.0f * M_PI/180.0f);
SpeakerAngle[3] = float2ALfp( 0.0f * M_PI/180.0f);
SpeakerAngle[4] = float2ALfp( 30.0f * M_PI/180.0f);
SpeakerAngle[5] = float2ALfp( 90.0f * M_PI/180.0f);
SpeakerAngle[6] = float2ALfp( 150.0f * M_PI/180.0f);
SetSpeakerArrangement("layout_71CHN", SpeakerAngle, Speaker2Chan, Device->NumChan);
break;
}
if(GetConfigValueBool(NULL, "scalemix", 0))
{
ALfp maxout = int2ALfp(1);;
for(s = 0;s < MAXCHANNELS;s++)
{
ALfp out = int2ALfp(0);
for(s2 = 0;s2 < MAXCHANNELS;s2++)
out = (out + Device->ChannelMatrix[s2][s]);
maxout = __max(maxout, out);
}
maxout = ALfpDiv(int2ALfp(1),maxout);
for(s = 0;s < MAXCHANNELS;s++)
{
for(s2 = 0;s2 < MAXCHANNELS;s2++)
Device->ChannelMatrix[s2][s] = ALfpMult(Device->ChannelMatrix[s2][s],maxout);
}
}
PanningLUT = Device->PanningLUT;
for(pos = 0; pos < LUT_NUM; pos++)
{
/* clear all values */
offset = MAXCHANNELS * pos;
for(s = 0; s < MAXCHANNELS; s++)
PanningLUT[offset+s] = int2ALfp(0);
if(Device->NumChan == 1)
{
PanningLUT[offset + Speaker2Chan[0]] = int2ALfp(1);
continue;
}
/* source angle */
Theta = aluLUTpos2Angle(pos);
/* set panning values */
for(s = 0; s < Device->NumChan - 1; s++)
{
if(Theta >= SpeakerAngle[s] && Theta < SpeakerAngle[s+1])
{
/* source between speaker s and speaker s+1 */
Alpha = ALfpDiv(ALfpMult(float2ALfp(M_PI_2), (Theta-SpeakerAngle[s])),
(SpeakerAngle[s+1]-SpeakerAngle[s]));
PanningLUT[offset + Speaker2Chan[s]] = __cos(Alpha);
PanningLUT[offset + Speaker2Chan[s+1]] = __sin(Alpha);
break;
}
}
if(s == Device->NumChan - 1)
{
/* source between last and first speaker */
if(Theta < SpeakerAngle[0])
Theta = (Theta + float2ALfp(2.0f * M_PI));
Alpha = ALfpDiv(ALfpMult(float2ALfp(M_PI_2), (Theta-SpeakerAngle[s])),
(float2ALfp(2.0f * M_PI) + SpeakerAngle[0]-SpeakerAngle[s]));
PanningLUT[offset + Speaker2Chan[s]] = __cos(Alpha);
PanningLUT[offset + Speaker2Chan[0]] = __sin(Alpha);
}
}
}

442
jni/OpenAL/Alc/portaudio.c Normal file
View File

@ -0,0 +1,442 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2007 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include <portaudio.h>
static void *pa_handle;
#define MAKE_FUNC(x) static typeof(x) * p##x
MAKE_FUNC(Pa_Initialize);
MAKE_FUNC(Pa_Terminate);
MAKE_FUNC(Pa_GetErrorText);
MAKE_FUNC(Pa_StartStream);
MAKE_FUNC(Pa_StopStream);
MAKE_FUNC(Pa_OpenStream);
MAKE_FUNC(Pa_CloseStream);
MAKE_FUNC(Pa_GetDefaultOutputDevice);
MAKE_FUNC(Pa_GetStreamInfo);
#undef MAKE_FUNC
static const ALCchar pa_device[] = "PortAudio Default";
void *pa_load(void)
{
if(!pa_handle)
{
PaError err;
#ifdef _WIN32
pa_handle = LoadLibrary("portaudio.dll");
#define LOAD_FUNC(x) do { \
p##x = (typeof(p##x))GetProcAddress(pa_handle, #x); \
if(!(p##x)) { \
AL_PRINT("Could not load %s from portaudio.dll\n", #x); \
FreeLibrary(pa_handle); \
pa_handle = NULL; \
return NULL; \
} \
} while(0)
#elif defined(HAVE_DLFCN_H)
const char *str;
#if defined(__APPLE__) && defined(__MACH__)
# define PALIB "libportaudio.2.dylib"
#else
# define PALIB "libportaudio.so.2"
#endif
pa_handle = dlopen(PALIB, RTLD_NOW);
dlerror();
#define LOAD_FUNC(f) do { \
p##f = (typeof(f)*)dlsym(pa_handle, #f); \
if((str=dlerror()) != NULL) \
{ \
dlclose(pa_handle); \
pa_handle = NULL; \
AL_PRINT("Could not load %s from "PALIB": %s\n", #f, str); \
return NULL; \
} \
} while(0)
#else
pa_handle = (void*)0xDEADBEEF;
#define LOAD_FUNC(f) p##f = f
#endif
if(!pa_handle)
return NULL;
LOAD_FUNC(Pa_Initialize);
LOAD_FUNC(Pa_Terminate);
LOAD_FUNC(Pa_GetErrorText);
LOAD_FUNC(Pa_StartStream);
LOAD_FUNC(Pa_StopStream);
LOAD_FUNC(Pa_OpenStream);
LOAD_FUNC(Pa_CloseStream);
LOAD_FUNC(Pa_GetDefaultOutputDevice);
LOAD_FUNC(Pa_GetStreamInfo);
#undef LOAD_FUNC
if((err=pPa_Initialize()) != paNoError)
{
AL_PRINT("Pa_Initialize() returned an error: %s\n", pPa_GetErrorText(err));
#ifdef _WIN32
FreeLibrary(pa_handle);
#elif defined(HAVE_DLFCN_H)
dlclose(pa_handle);
#endif
pa_handle = NULL;
return NULL;
}
}
return pa_handle;
}
typedef struct {
PaStream *stream;
ALuint update_size;
RingBuffer *ring;
} pa_data;
static int pa_callback(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
const PaStreamCallbackFlags statusFlags, void *userData)
{
ALCdevice *device = (ALCdevice*)userData;
(void)inputBuffer;
(void)timeInfo;
(void)statusFlags;
aluMixData(device, outputBuffer, framesPerBuffer);
return 0;
}
static int pa_capture_cb(const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo,
const PaStreamCallbackFlags statusFlags, void *userData)
{
ALCdevice *device = (ALCdevice*)userData;
pa_data *data = (pa_data*)device->ExtraData;
(void)outputBuffer;
(void)timeInfo;
(void)statusFlags;
WriteRingBuffer(data->ring, inputBuffer, framesPerBuffer);
return 0;
}
static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
const PaStreamInfo *streamInfo;
PaStreamParameters outParams;
pa_data *data;
PaError err;
if(!deviceName)
deviceName = pa_device;
else if(strcmp(deviceName, pa_device) != 0)
return ALC_FALSE;
if(!pa_load())
return ALC_FALSE;
data = (pa_data*)calloc(1, sizeof(pa_data));
data->update_size = device->UpdateSize;
device->ExtraData = data;
outParams.device = GetConfigValueInt("port", "device", -1);
if(outParams.device < 0)
outParams.device = pPa_GetDefaultOutputDevice();
outParams.suggestedLatency = (device->UpdateSize*device->NumUpdates) /
(float)device->Frequency;
outParams.hostApiSpecificStreamInfo = NULL;
switch(device->FmtType)
{
case DevFmtByte:
outParams.sampleFormat = paInt8;
break;
case DevFmtUByte:
outParams.sampleFormat = paUInt8;
break;
case DevFmtUShort:
device->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
outParams.sampleFormat = paInt16;
break;
case DevFmtFloat:
outParams.sampleFormat = paFloat32;
break;
}
outParams.channelCount = ChannelsFromDevFmt(device->FmtChans);
SetDefaultChannelOrder(device);
err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
device->UpdateSize, paNoFlag, pa_callback, device);
if(err != paNoError)
{
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
device->ExtraData = NULL;
free(data);
return ALC_FALSE;
}
streamInfo = pPa_GetStreamInfo(data->stream);
device->szDeviceName = strdup(deviceName);
device->Frequency = streamInfo->sampleRate;
return ALC_TRUE;
}
static void pa_close_playback(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
PaError err;
err = pPa_CloseStream(data->stream);
if(err != paNoError)
AL_PRINT("Error closing stream: %s\n", pPa_GetErrorText(err));
free(data);
device->ExtraData = NULL;
}
static ALCboolean pa_reset_playback(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
const PaStreamInfo *streamInfo;
PaError err;
streamInfo = pPa_GetStreamInfo(data->stream);
device->Frequency = streamInfo->sampleRate;
device->UpdateSize = data->update_size;
err = pPa_StartStream(data->stream);
if(err != paNoError)
{
AL_PRINT("Pa_StartStream() returned an error: %s\n", pPa_GetErrorText(err));
return ALC_FALSE;
}
return ALC_TRUE;
}
static void pa_stop_playback(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
PaError err;
err = pPa_StopStream(data->stream);
if(err != paNoError)
AL_PRINT("Error stopping stream: %s\n", pPa_GetErrorText(err));
}
static ALCboolean pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
PaStreamParameters inParams;
ALuint frame_size;
pa_data *data;
PaError err;
if(!deviceName)
deviceName = pa_device;
else if(strcmp(deviceName, pa_device) != 0)
return ALC_FALSE;
if(!pa_load())
return ALC_FALSE;
data = (pa_data*)calloc(1, sizeof(pa_data));
if(data == NULL)
{
alcSetError(device, ALC_OUT_OF_MEMORY);
return ALC_FALSE;
}
frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates);
if(data->ring == NULL)
{
alcSetError(device, ALC_OUT_OF_MEMORY);
goto error;
}
inParams.device = GetConfigValueInt("port", "capture", -1);
if(inParams.device < 0)
inParams.device = pPa_GetDefaultOutputDevice();
inParams.suggestedLatency = 0.0f;
inParams.hostApiSpecificStreamInfo = NULL;
switch(device->FmtType)
{
case DevFmtByte:
inParams.sampleFormat = paInt8;
break;
case DevFmtUByte:
inParams.sampleFormat = paUInt8;
break;
case DevFmtShort:
inParams.sampleFormat = paInt16;
break;
case DevFmtFloat:
inParams.sampleFormat = paFloat32;
break;
case DevFmtUShort:
AL_PRINT("Unsigned short not supported\n");
goto error;
}
inParams.channelCount = ChannelsFromDevFmt(device->FmtChans);
err = pPa_OpenStream(&data->stream, &inParams, NULL, device->Frequency,
paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device);
if(err != paNoError)
{
AL_PRINT("Pa_OpenStream() returned an error: %s\n", pPa_GetErrorText(err));
goto error;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
error:
DestroyRingBuffer(data->ring);
free(data);
return ALC_FALSE;
}
static void pa_close_capture(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
PaError err;
err = pPa_CloseStream(data->stream);
if(err != paNoError)
AL_PRINT("Error closing stream: %s\n", pPa_GetErrorText(err));
free(data);
device->ExtraData = NULL;
}
static void pa_start_capture(ALCdevice *device)
{
pa_data *data = device->ExtraData;
PaError err;
err = pPa_StartStream(data->stream);
if(err != paNoError)
AL_PRINT("Error starting stream: %s\n", pPa_GetErrorText(err));
}
static void pa_stop_capture(ALCdevice *device)
{
pa_data *data = (pa_data*)device->ExtraData;
PaError err;
err = pPa_StopStream(data->stream);
if(err != paNoError)
AL_PRINT("Error stopping stream: %s\n", pPa_GetErrorText(err));
}
static void pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
{
pa_data *data = device->ExtraData;
if(samples <= (ALCuint)RingBufferSize(data->ring))
ReadRingBuffer(data->ring, buffer, samples);
else
alcSetError(device, ALC_INVALID_VALUE);
}
static ALCuint pa_available_samples(ALCdevice *device)
{
pa_data *data = device->ExtraData;
return RingBufferSize(data->ring);
}
static const BackendFuncs pa_funcs = {
pa_open_playback,
pa_close_playback,
pa_reset_playback,
pa_stop_playback,
pa_open_capture,
pa_close_capture,
pa_start_capture,
pa_stop_capture,
pa_capture_samples,
pa_available_samples
};
void alc_pa_init(BackendFuncs *func_list)
{
*func_list = pa_funcs;
}
void alc_pa_deinit(void)
{
if(pa_handle)
{
pPa_Terminate();
#ifdef _WIN32
FreeLibrary(pa_handle);
#elif defined(HAVE_DLFCN_H)
dlclose(pa_handle);
#endif
pa_handle = NULL;
}
}
void alc_pa_probe(int type)
{
if(!pa_load()) return;
if(type == DEVICE_PROBE)
AppendDeviceList(pa_device);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(pa_device);
else if(type == CAPTURE_DEVICE_PROBE)
AppendCaptureDeviceList(pa_device);
}

1358
jni/OpenAL/Alc/pulseaudio.c Normal file

File diff suppressed because it is too large Load Diff

304
jni/OpenAL/Alc/solaris.c Normal file
View File

@ -0,0 +1,304 @@
/**
* 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 <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <unistd.h>
#include <errno.h>
#include <math.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include <sys/audioio.h>
static const ALCchar solaris_device[] = "Solaris Default";
typedef struct {
int fd;
volatile int killNow;
ALvoid *thread;
ALubyte *mix_data;
int data_size;
} solaris_data;
static ALuint SolarisProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
solaris_data *data = (solaris_data*)pDevice->ExtraData;
ALint frameSize;
int wrote;
SetRTPriority();
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
while(!data->killNow && pDevice->Connected)
{
ALint len = data->data_size;
ALubyte *WritePtr = data->mix_data;
aluMixData(pDevice, WritePtr, len/frameSize);
while(len > 0 && !data->killNow)
{
wrote = write(data->fd, WritePtr, len);
if(wrote < 0)
{
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
{
AL_PRINT("write failed: %s\n", strerror(errno));
aluHandleDisconnect(pDevice);
break;
}
Sleep(1);
continue;
}
len -= wrote;
WritePtr += wrote;
}
}
return 0;
}
static ALCboolean solaris_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
char driver[64];
solaris_data *data;
strncpy(driver, GetConfigValue("solaris", "device", "/dev/audio"), sizeof(driver)-1);
driver[sizeof(driver)-1] = 0;
if(!deviceName)
deviceName = solaris_device;
else if(strcmp(deviceName, solaris_device) != 0)
return ALC_FALSE;
data = (solaris_data*)calloc(1, sizeof(solaris_data));
data->killNow = 0;
data->fd = open(driver, O_WRONLY);
if(data->fd == -1)
{
free(data);
AL_PRINT("Could not open %s: %s\n", driver, strerror(errno));
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
static void solaris_close_playback(ALCdevice *device)
{
solaris_data *data = (solaris_data*)device->ExtraData;
close(data->fd);
free(data);
device->ExtraData = NULL;
}
static ALCboolean solaris_reset_playback(ALCdevice *device)
{
solaris_data *data = (solaris_data*)device->ExtraData;
audio_info_t info;
ALuint frameSize;
int numChannels;
AUDIO_INITINFO(&info);
info.play.sample_rate = device->Frequency;
if(device->FmtChans != DevFmtMono)
device->FmtChans = DevFmtStereo;
numChannels = ChannelsFromDevFmt(device->FmtChans);
info.play.channels = numChannels;
switch(device->FmtType)
{
case DevFmtByte:
info.play.precision = 8;
info.play.encoding = AUDIO_ENCODING_LINEAR;
break;
case DevFmtUByte:
info.play.precision = 8;
info.play.encoding = AUDIO_ENCODING_LINEAR8;
break;
case DevFmtUShort:
case DevFmtFloat:
device->FmtType = DevFmtShort;
/* fall-through */
case DevFmtShort:
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_LINEAR;
break;
}
frameSize = numChannels * BytesFromDevFmt(device->FmtType);
info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize;
if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0)
{
AL_PRINT("ioctl failed: %s\n", strerror(errno));
return ALC_FALSE;
}
if(ChannelsFromDevFmt(device->FmtChans) != info.play.channels)
{
AL_PRINT("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), info.play.channels);
return ALC_FALSE;
}
if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR &&
device->FmtType == DevFmtByte) ||
(info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 &&
device->FmtType == DevFmtUByte) ||
(info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR &&
device->FmtType == DevFmtShort)))
{
AL_PRINT("Could not set %#x sample type, got %d (%#x)\n",
device->FmtType, info.play.precision, info.play.encoding);
return ALC_FALSE;
}
device->Frequency = info.play.sample_rate;
device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1;
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
SetDefaultChannelOrder(device);
data->thread = StartThread(SolarisProc, device);
if(data->thread == NULL)
{
free(data->mix_data);
data->mix_data = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void solaris_stop_playback(ALCdevice *device)
{
solaris_data *data = (solaris_data*)device->ExtraData;
if(!data->thread)
return;
data->killNow = 1;
StopThread(data->thread);
data->thread = NULL;
data->killNow = 0;
if(ioctl(data->fd, AUDIO_DRAIN) < 0)
AL_PRINT("Error draining device: %s\n", strerror(errno));
free(data->mix_data);
data->mix_data = NULL;
}
static ALCboolean solaris_open_capture(ALCdevice *device, const ALCchar *deviceName)
{
(void)device;
(void)deviceName;
return ALC_FALSE;
}
static void solaris_close_capture(ALCdevice *device)
{
(void)device;
}
static void solaris_start_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void solaris_stop_capture(ALCdevice *pDevice)
{
(void)pDevice;
}
static void solaris_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
(void)pDevice;
(void)pBuffer;
(void)lSamples;
}
static ALCuint solaris_available_samples(ALCdevice *pDevice)
{
(void)pDevice;
return 0;
}
BackendFuncs solaris_funcs = {
solaris_open_playback,
solaris_close_playback,
solaris_reset_playback,
solaris_stop_playback,
solaris_open_capture,
solaris_close_capture,
solaris_start_capture,
solaris_stop_capture,
solaris_capture_samples,
solaris_available_samples
};
void alc_solaris_init(BackendFuncs *func_list)
{
*func_list = solaris_funcs;
}
void alc_solaris_deinit(void)
{
}
void alc_solaris_probe(int type)
{
#ifdef HAVE_STAT
struct stat buf;
if(stat(GetConfigValue("solaris", "device", "/dev/audio"), &buf) != 0)
return;
#endif
if(type == DEVICE_PROBE)
AppendDeviceList(solaris_device);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(solaris_device);
}

355
jni/OpenAL/Alc/wave.c Normal file
View File

@ -0,0 +1,355 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2007 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
typedef struct {
FILE *f;
long DataStart;
ALvoid *buffer;
ALuint size;
volatile int killNow;
ALvoid *thread;
} wave_data;
static const ALCchar waveDevice[] = "Wave File Writer";
static const ALubyte SUBTYPE_PCM[] = {
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71
};
static const ALubyte SUBTYPE_FLOAT[] = {
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71
};
static const ALuint channel_masks[] = {
0, /* invalid */
0x4, /* Mono */
0x1 | 0x2, /* Stereo */
0, /* 3 channel */
0x1 | 0x2 | 0x10 | 0x20, /* Quad */
0, /* 5 channel */
0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20, /* 5.1 */
0x1 | 0x2 | 0x4 | 0x8 | 0x100 | 0x200 | 0x400, /* 6.1 */
0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x200 | 0x400, /* 7.1 */
};
static void fwrite16le(ALushort val, FILE *f)
{
fputc(val&0xff, f);
fputc((val>>8)&0xff, f);
}
static void fwrite32le(ALuint val, FILE *f)
{
fputc(val&0xff, f);
fputc((val>>8)&0xff, f);
fputc((val>>16)&0xff, f);
fputc((val>>24)&0xff, f);
}
static ALuint WaveProc(ALvoid *ptr)
{
ALCdevice *pDevice = (ALCdevice*)ptr;
wave_data *data = (wave_data*)pDevice->ExtraData;
ALuint frameSize;
ALuint now, start;
ALuint64 avail, done;
size_t fs;
union {
short s;
char b[sizeof(short)];
} uSB;
const ALuint restTime = (ALuint64)pDevice->UpdateSize * 1000 /
pDevice->Frequency / 2;
uSB.s = 1;
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
done = 0;
start = timeGetTime();
while(!data->killNow && pDevice->Connected)
{
now = timeGetTime();
avail = (ALuint64)(now-start) * pDevice->Frequency / 1000;
if(avail < done)
{
/* Timer wrapped. Add the remainder of the cycle to the available
* count and reset the number of samples done */
avail += (ALuint64)0xFFFFFFFFu*pDevice->Frequency/1000 - done;
done = 0;
}
if(avail-done < pDevice->UpdateSize)
{
Sleep(restTime);
continue;
}
while(avail-done >= pDevice->UpdateSize)
{
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
done += pDevice->UpdateSize;
if(uSB.b[0] != 1)
{
ALuint bytesize = BytesFromDevFmt(pDevice->FmtType);
ALubyte *bytes = data->buffer;
ALuint i;
if(bytesize == 1)
{
for(i = 0;i < data->size;i++)
fputc(bytes[i], data->f);
}
else if(bytesize == 2)
{
for(i = 0;i < data->size;i++)
fputc(bytes[i^1], data->f);
}
else if(bytesize == 4)
{
for(i = 0;i < data->size;i++)
fputc(bytes[i^3], data->f);
}
}
else
fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize,
data->f);
if(ferror(data->f))
{
AL_PRINT("Error writing to file\n");
aluHandleDisconnect(pDevice);
break;
}
}
}
return 0;
}
static ALCboolean wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
{
wave_data *data;
const char *fname;
fname = GetConfigValue("wave", "file", "");
if(!fname[0])
return ALC_FALSE;
if(!deviceName)
deviceName = waveDevice;
else if(strcmp(deviceName, waveDevice) != 0)
return ALC_FALSE;
data = (wave_data*)calloc(1, sizeof(wave_data));
data->f = fopen(fname, "wb");
if(!data->f)
{
free(data);
AL_PRINT("Could not open file '%s': %s\n", fname, strerror(errno));
return ALC_FALSE;
}
device->szDeviceName = strdup(deviceName);
device->ExtraData = data;
return ALC_TRUE;
}
static void wave_close_playback(ALCdevice *device)
{
wave_data *data = (wave_data*)device->ExtraData;
fclose(data->f);
free(data);
device->ExtraData = NULL;
}
static ALCboolean wave_reset_playback(ALCdevice *device)
{
wave_data *data = (wave_data*)device->ExtraData;
ALuint channels=0, bits=0;
size_t val;
fseek(data->f, 0, SEEK_SET);
clearerr(data->f);
switch(device->FmtType)
{
case DevFmtByte:
device->FmtType = DevFmtUByte;
break;
case DevFmtUShort:
device->FmtType = DevFmtShort;
break;
case DevFmtUByte:
case DevFmtShort:
case DevFmtFloat:
break;
}
bits = BytesFromDevFmt(device->FmtType) * 8;
channels = ChannelsFromDevFmt(device->FmtChans);
fprintf(data->f, "RIFF");
fwrite32le(0xFFFFFFFF, data->f); // 'RIFF' header len; filled in at close
fprintf(data->f, "WAVE");
fprintf(data->f, "fmt ");
fwrite32le(40, data->f); // 'fmt ' header len; 40 bytes for EXTENSIBLE
// 16-bit val, format type id (extensible: 0xFFFE)
fwrite16le(0xFFFE, data->f);
// 16-bit val, channel count
fwrite16le(channels, data->f);
// 32-bit val, frequency
fwrite32le(device->Frequency, data->f);
// 32-bit val, bytes per second
fwrite32le(device->Frequency * channels * bits / 8, data->f);
// 16-bit val, frame size
fwrite16le(channels * bits / 8, data->f);
// 16-bit val, bits per sample
fwrite16le(bits, data->f);
// 16-bit val, extra byte count
fwrite16le(22, data->f);
// 16-bit val, valid bits per sample
fwrite16le(bits, data->f);
// 32-bit val, channel mask
fwrite32le(channel_masks[channels], data->f);
// 16 byte GUID, sub-type format
val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f);
fprintf(data->f, "data");
fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close
if(ferror(data->f))
{
AL_PRINT("Error writing header: %s\n", strerror(errno));
return ALC_FALSE;
}
data->DataStart = ftell(data->f);
data->size = device->UpdateSize * channels * bits / 8;
data->buffer = malloc(data->size);
if(!data->buffer)
{
AL_PRINT("buffer malloc failed\n");
return ALC_FALSE;
}
SetDefaultWFXChannelOrder(device);
data->thread = StartThread(WaveProc, device);
if(data->thread == NULL)
{
free(data->buffer);
data->buffer = NULL;
return ALC_FALSE;
}
return ALC_TRUE;
}
static void wave_stop_playback(ALCdevice *device)
{
wave_data *data = (wave_data*)device->ExtraData;
ALuint dataLen;
long size;
if(!data->thread)
return;
data->killNow = 1;
StopThread(data->thread);
data->thread = NULL;
data->killNow = 0;
free(data->buffer);
data->buffer = NULL;
size = ftell(data->f);
if(size > 0)
{
dataLen = size - data->DataStart;
if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0)
fwrite32le(dataLen, data->f); // 'data' header len
if(fseek(data->f, 4, SEEK_SET) == 0)
fwrite32le(size-8, data->f); // 'WAVE' header len
}
}
static ALCboolean wave_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
{
(void)pDevice;
(void)deviceName;
return ALC_FALSE;
}
BackendFuncs wave_funcs = {
wave_open_playback,
wave_close_playback,
wave_reset_playback,
wave_stop_playback,
wave_open_capture,
NULL,
NULL,
NULL,
NULL,
NULL
};
void alc_wave_init(BackendFuncs *func_list)
{
*func_list = wave_funcs;
}
void alc_wave_deinit(void)
{
}
void alc_wave_probe(int type)
{
if(!ConfigValueExists("wave", "file"))
return;
if(type == DEVICE_PROBE)
AppendDeviceList(waveDevice);
else if(type == ALL_DEVICE_PROBE)
AppendAllDeviceList(waveDevice);
}

784
jni/OpenAL/Alc/winmm.c Normal file
View File

@ -0,0 +1,784 @@
/**
* 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"
#define _WIN32_WINNT 0x0500
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <windows.h>
#include <mmsystem.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
typedef struct {
// MMSYSTEM Device
volatile ALboolean bWaveShutdown;
HANDLE hWaveHdrEvent;
HANDLE hWaveThreadEvent;
HANDLE hWaveThread;
DWORD ulWaveThreadID;
LONG lWaveBuffersCommitted;
WAVEHDR WaveBuffer[4];
union {
HWAVEIN In;
HWAVEOUT Out;
} hWaveHandle;
ALsizei Frequency;
RingBuffer *pRing;
} WinMMData;
static const ALCchar woDefault[] = "WaveOut Default";
static ALCchar **PlaybackDeviceList;
static ALuint NumPlaybackDevices;
static ALCchar **CaptureDeviceList;
static ALuint NumCaptureDevices;
static void ProbePlaybackDevices(void)
{
ALuint i;
for(i = 0;i < NumPlaybackDevices;i++)
free(PlaybackDeviceList[i]);
NumPlaybackDevices = waveOutGetNumDevs();
PlaybackDeviceList = realloc(PlaybackDeviceList, sizeof(ALCchar*) * NumPlaybackDevices);
for(i = 0;i < NumPlaybackDevices;i++)
{
WAVEOUTCAPS WaveCaps;
PlaybackDeviceList[i] = NULL;
if(waveOutGetDevCaps(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR)
{
char name[1024];
ALuint count, j;
count = 0;
do {
if(count == 0)
snprintf(name, sizeof(name), "%s via WaveOut", WaveCaps.szPname);
else
snprintf(name, sizeof(name), "%s #%d via WaveOut", WaveCaps.szPname, count+1);
count++;
for(j = 0;j < i;j++)
{
if(strcmp(name, PlaybackDeviceList[j]) == 0)
break;
}
} while(j != i);
PlaybackDeviceList[i] = strdup(name);
}
}
}
static void ProbeCaptureDevices(void)
{
ALuint i;
for(i = 0;i < NumCaptureDevices;i++)
free(CaptureDeviceList[i]);
NumCaptureDevices = waveInGetNumDevs();
CaptureDeviceList = realloc(CaptureDeviceList, sizeof(ALCchar*) * NumCaptureDevices);
for(i = 0;i < NumCaptureDevices;i++)
{
WAVEINCAPS WaveInCaps;
CaptureDeviceList[i] = NULL;
if(waveInGetDevCaps(i, &WaveInCaps, sizeof(WAVEINCAPS)) == MMSYSERR_NOERROR)
{
char name[1024];
ALuint count, j;
count = 0;
do {
if(count == 0)
snprintf(name, sizeof(name), "%s via WaveIn", WaveInCaps.szPname);
else
snprintf(name, sizeof(name), "%s #%d via WaveIn", WaveInCaps.szPname, count+1);
count++;
for(j = 0;j < i;j++)
{
if(strcmp(name, CaptureDeviceList[j]) == 0)
break;
}
} while(j != i);
CaptureDeviceList[i] = strdup(name);
}
}
}
/*
WaveOutProc
Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and
returns to the application (for more data)
*/
static void CALLBACK WaveOutProc(HWAVEOUT hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2)
{
ALCdevice *pDevice = (ALCdevice*)dwInstance;
WinMMData *pData = pDevice->ExtraData;
(void)hDevice;
(void)dwParam2;
if(uMsg != WOM_DONE)
return;
// Decrement number of buffers in use
InterlockedDecrement(&pData->lWaveBuffersCommitted);
if(pData->bWaveShutdown == AL_FALSE)
{
// Notify Wave Processor Thread that a Wave Header has returned
PostThreadMessage(pData->ulWaveThreadID, uMsg, 0, dwParam1);
}
else
{
if(pData->lWaveBuffersCommitted == 0)
{
// Signal Wave Buffers Returned event
if(pData->hWaveHdrEvent)
SetEvent(pData->hWaveHdrEvent);
// Post 'Quit' Message to WaveOut Processor Thread
PostThreadMessage(pData->ulWaveThreadID, WM_QUIT, 0, 0);
}
}
}
/*
PlaybackThreadProc
Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its
audio data.
*/
static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter)
{
ALCdevice *pDevice = (ALCdevice*)lpParameter;
WinMMData *pData = pDevice->ExtraData;
LPWAVEHDR pWaveHdr;
ALuint FrameSize;
MSG msg;
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message != WOM_DONE || pData->bWaveShutdown)
continue;
pWaveHdr = ((LPWAVEHDR)msg.lParam);
aluMixData(pDevice, pWaveHdr->lpData, pWaveHdr->dwBufferLength/FrameSize);
// Send buffer back to play more data
waveOutWrite(pData->hWaveHandle.Out, pWaveHdr, sizeof(WAVEHDR));
InterlockedIncrement(&pData->lWaveBuffersCommitted);
}
// Signal Wave Thread completed event
if(pData->hWaveThreadEvent)
SetEvent(pData->hWaveThreadEvent);
ExitThread(0);
return 0;
}
/*
WaveInProc
Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and
returns to the application (with more data)
*/
static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,DWORD_PTR dwParam1,DWORD_PTR dwParam2)
{
ALCdevice *pDevice = (ALCdevice*)dwInstance;
WinMMData *pData = pDevice->ExtraData;
(void)hDevice;
(void)dwParam2;
if(uMsg != WIM_DATA)
return;
// Decrement number of buffers in use
InterlockedDecrement(&pData->lWaveBuffersCommitted);
if(pData->bWaveShutdown == AL_FALSE)
{
// Notify Wave Processor Thread that a Wave Header has returned
PostThreadMessage(pData->ulWaveThreadID,uMsg,0,dwParam1);
}
else
{
if(pData->lWaveBuffersCommitted == 0)
{
// Signal Wave Buffers Returned event
if(pData->hWaveHdrEvent)
SetEvent(pData->hWaveHdrEvent);
// Post 'Quit' Message to WaveIn Processor Thread
PostThreadMessage(pData->ulWaveThreadID,WM_QUIT,0,0);
}
}
}
/*
CaptureThreadProc
Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new
audio data.
*/
static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter)
{
ALCdevice *pDevice = (ALCdevice*)lpParameter;
WinMMData *pData = pDevice->ExtraData;
LPWAVEHDR pWaveHdr;
ALuint FrameSize;
MSG msg;
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message != WIM_DATA || pData->bWaveShutdown)
continue;
pWaveHdr = ((LPWAVEHDR)msg.lParam);
WriteRingBuffer(pData->pRing, (ALubyte*)pWaveHdr->lpData,
pWaveHdr->dwBytesRecorded/FrameSize);
// Send buffer back to capture more data
waveInAddBuffer(pData->hWaveHandle.In,pWaveHdr,sizeof(WAVEHDR));
InterlockedIncrement(&pData->lWaveBuffersCommitted);
}
// Signal Wave Thread completed event
if(pData->hWaveThreadEvent)
SetEvent(pData->hWaveThreadEvent);
ExitThread(0);
return 0;
}
static ALCboolean WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName)
{
WAVEFORMATEX wfexFormat;
WinMMData *pData = NULL;
UINT lDeviceID = 0;
MMRESULT res;
ALuint i = 0;
// Find the Device ID matching the deviceName if valid
if(!deviceName || strcmp(deviceName, woDefault) == 0)
lDeviceID = WAVE_MAPPER;
else
{
if(!PlaybackDeviceList)
ProbePlaybackDevices();
for(i = 0;i < NumPlaybackDevices;i++)
{
if(PlaybackDeviceList[i] &&
strcmp(deviceName, PlaybackDeviceList[i]) == 0)
{
lDeviceID = i;
break;
}
}
if(i == NumPlaybackDevices)
return ALC_FALSE;
}
pData = calloc(1, sizeof(*pData));
if(!pData)
{
alcSetError(pDevice, ALC_OUT_OF_MEMORY);
return ALC_FALSE;
}
pDevice->ExtraData = pData;
if(pDevice->FmtChans != DevFmtMono)
pDevice->FmtChans = DevFmtStereo;
switch(pDevice->FmtType)
{
case DevFmtByte:
pDevice->FmtType = DevFmtUByte;
break;
case DevFmtUShort:
case DevFmtFloat:
pDevice->FmtType = DevFmtShort;
break;
case DevFmtUByte:
case DevFmtShort:
break;
}
memset(&wfexFormat, 0, sizeof(WAVEFORMATEX));
wfexFormat.wFormatTag = WAVE_FORMAT_PCM;
wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans);
wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8;
wfexFormat.nBlockAlign = wfexFormat.wBitsPerSample *
wfexFormat.nChannels / 8;
wfexFormat.nSamplesPerSec = pDevice->Frequency;
wfexFormat.nAvgBytesPerSec = wfexFormat.nSamplesPerSec *
wfexFormat.nBlockAlign;
wfexFormat.cbSize = 0;
if((res=waveOutOpen(&pData->hWaveHandle.Out, lDeviceID, &wfexFormat, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
{
AL_PRINT("waveInOpen failed: %u\n", res);
goto failure;
}
pData->hWaveHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveOutAllHeadersReturned");
pData->hWaveThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveOutThreadDestroyed");
if(pData->hWaveHdrEvent == NULL || pData->hWaveThreadEvent == NULL)
{
AL_PRINT("CreateEvent failed: %lu\n", GetLastError());
goto failure;
}
pData->Frequency = pDevice->Frequency;
pDevice->szDeviceName = strdup((lDeviceID==WAVE_MAPPER) ? woDefault :
PlaybackDeviceList[lDeviceID]);
return ALC_TRUE;
failure:
if(pData->hWaveThreadEvent)
CloseHandle(pData->hWaveThreadEvent);
if(pData->hWaveHdrEvent)
CloseHandle(pData->hWaveHdrEvent);
if(pData->hWaveHandle.Out)
waveOutClose(pData->hWaveHandle.Out);
free(pData);
pDevice->ExtraData = NULL;
return ALC_FALSE;
}
static void WinMMClosePlayback(ALCdevice *device)
{
WinMMData *pData = (WinMMData*)device->ExtraData;
// Close the Wave device
CloseHandle(pData->hWaveThreadEvent);
pData->hWaveThreadEvent = 0;
CloseHandle(pData->hWaveHdrEvent);
pData->hWaveHdrEvent = 0;
waveInClose(pData->hWaveHandle.In);
pData->hWaveHandle.In = 0;
free(pData);
device->ExtraData = NULL;
}
static ALCboolean WinMMResetPlayback(ALCdevice *device)
{
WinMMData *pData = (WinMMData*)device->ExtraData;
ALbyte *BufferData;
ALint lBufferSize;
ALuint i;
pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &pData->ulWaveThreadID);
if(pData->hWaveThread == NULL)
return ALC_FALSE;
device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize *
pData->Frequency / device->Frequency);
device->Frequency = pData->Frequency;
pData->lWaveBuffersCommitted = 0;
// Create 4 Buffers
lBufferSize = device->UpdateSize*device->NumUpdates / 4;
lBufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
BufferData = calloc(4, lBufferSize);
for(i = 0;i < 4;i++)
{
memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR));
pData->WaveBuffer[i].dwBufferLength = lBufferSize;
pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
(pData->WaveBuffer[i-1].lpData +
pData->WaveBuffer[i-1].dwBufferLength));
waveOutPrepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR));
waveOutWrite(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR));
InterlockedIncrement(&pData->lWaveBuffersCommitted);
}
return ALC_TRUE;
}
static void WinMMStopPlayback(ALCdevice *device)
{
WinMMData *pData = (WinMMData*)device->ExtraData;
int i;
if(pData->hWaveThread == NULL)
return;
// Set flag to stop processing headers
pData->bWaveShutdown = AL_TRUE;
// Wait for signal that all Wave Buffers have returned
WaitForSingleObjectEx(pData->hWaveHdrEvent, 5000, FALSE);
// Wait for signal that Wave Thread has been destroyed
WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE);
CloseHandle(pData->hWaveThread);
pData->hWaveThread = 0;
pData->bWaveShutdown = AL_FALSE;
// Release the wave buffers
for(i = 0;i < 4;i++)
{
waveOutUnprepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR));
if(i == 0)
free(pData->WaveBuffer[i].lpData);
pData->WaveBuffer[i].lpData = NULL;
}
}
static ALCboolean WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
{
WAVEFORMATEX wfexCaptureFormat;
DWORD ulCapturedDataSize;
WinMMData *pData = NULL;
UINT lDeviceID = 0;
ALbyte *BufferData;
ALint lBufferSize;
MMRESULT res;
ALuint i;
if(!CaptureDeviceList)
ProbeCaptureDevices();
// Find the Device ID matching the deviceName if valid
if(deviceName)
{
for(i = 0;i < NumCaptureDevices;i++)
{
if(CaptureDeviceList[i] &&
strcmp(deviceName, CaptureDeviceList[i]) == 0)
{
lDeviceID = i;
break;
}
}
}
else
{
for(i = 0;i < NumCaptureDevices;i++)
{
if(CaptureDeviceList[i])
{
lDeviceID = i;
break;
}
}
}
if(i == NumCaptureDevices)
return ALC_FALSE;
pData = calloc(1, sizeof(*pData));
if(!pData)
{
alcSetError(pDevice, ALC_OUT_OF_MEMORY);
return ALC_FALSE;
}
pDevice->ExtraData = pData;
if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) ||
(pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort))
{
alcSetError(pDevice, ALC_INVALID_ENUM);
goto failure;
}
memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));
wfexCaptureFormat.wFormatTag = WAVE_FORMAT_PCM;
wfexCaptureFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans);
wfexCaptureFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8;
wfexCaptureFormat.nBlockAlign = wfexCaptureFormat.wBitsPerSample *
wfexCaptureFormat.nChannels / 8;
wfexCaptureFormat.nSamplesPerSec = pDevice->Frequency;
wfexCaptureFormat.nAvgBytesPerSec = wfexCaptureFormat.nSamplesPerSec *
wfexCaptureFormat.nBlockAlign;
wfexCaptureFormat.cbSize = 0;
if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &wfexCaptureFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
{
AL_PRINT("waveInOpen failed: %u\n", res);
goto failure;
}
pData->hWaveHdrEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInAllHeadersReturned");
pData->hWaveThreadEvent = CreateEvent(NULL, AL_TRUE, AL_FALSE, "WaveInThreadDestroyed");
if(pData->hWaveHdrEvent == NULL || pData->hWaveThreadEvent == NULL)
{
AL_PRINT("CreateEvent failed: %lu\n", GetLastError());
goto failure;
}
pData->Frequency = pDevice->Frequency;
// Allocate circular memory buffer for the captured audio
ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates;
// Make sure circular buffer is at least 100ms in size
if(ulCapturedDataSize < (wfexCaptureFormat.nSamplesPerSec / 10))
ulCapturedDataSize = wfexCaptureFormat.nSamplesPerSec / 10;
pData->pRing = CreateRingBuffer(wfexCaptureFormat.nBlockAlign, ulCapturedDataSize);
if(!pData->pRing)
goto failure;
pData->lWaveBuffersCommitted = 0;
// Create 4 Buffers of 50ms each
lBufferSize = wfexCaptureFormat.nAvgBytesPerSec / 20;
lBufferSize -= (lBufferSize % wfexCaptureFormat.nBlockAlign);
BufferData = calloc(4, lBufferSize);
if(!BufferData)
goto failure;
for(i = 0;i < 4;i++)
{
memset(&pData->WaveBuffer[i], 0, sizeof(WAVEHDR));
pData->WaveBuffer[i].dwBufferLength = lBufferSize;
pData->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
(pData->WaveBuffer[i-1].lpData +
pData->WaveBuffer[i-1].dwBufferLength));
pData->WaveBuffer[i].dwFlags = 0;
pData->WaveBuffer[i].dwLoops = 0;
waveInPrepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
waveInAddBuffer(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
InterlockedIncrement(&pData->lWaveBuffersCommitted);
}
pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID);
if (pData->hWaveThread == NULL)
goto failure;
pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
return ALC_TRUE;
failure:
if(pData->hWaveThread)
CloseHandle(pData->hWaveThread);
for(i = 0;i < 4;i++)
{
if(pData->WaveBuffer[i].lpData)
{
waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
if(i == 0)
free(pData->WaveBuffer[i].lpData);
}
}
if(pData->pRing)
DestroyRingBuffer(pData->pRing);
if(pData->hWaveThreadEvent)
CloseHandle(pData->hWaveThreadEvent);
if(pData->hWaveHdrEvent)
CloseHandle(pData->hWaveHdrEvent);
if(pData->hWaveHandle.In)
waveInClose(pData->hWaveHandle.In);
free(pData);
pDevice->ExtraData = NULL;
return ALC_FALSE;
}
static void WinMMCloseCapture(ALCdevice *pDevice)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
int i;
// Call waveOutReset to shutdown wave device
pData->bWaveShutdown = AL_TRUE;
waveInReset(pData->hWaveHandle.In);
// Wait for signal that all Wave Buffers have returned
WaitForSingleObjectEx(pData->hWaveHdrEvent, 5000, FALSE);
// Wait for signal that Wave Thread has been destroyed
WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE);
CloseHandle(pData->hWaveThread);
pData->hWaveThread = 0;
// Release the wave buffers
for(i = 0;i < 4;i++)
{
waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
if(i == 0)
free(pData->WaveBuffer[i].lpData);
pData->WaveBuffer[i].lpData = NULL;
}
DestroyRingBuffer(pData->pRing);
pData->pRing = NULL;
// Close the Wave device
CloseHandle(pData->hWaveThreadEvent);
pData->hWaveThreadEvent = 0;
CloseHandle(pData->hWaveHdrEvent);
pData->hWaveHdrEvent = 0;
waveInClose(pData->hWaveHandle.In);
pData->hWaveHandle.In = 0;
free(pData);
pDevice->ExtraData = NULL;
}
static void WinMMStartCapture(ALCdevice *pDevice)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
waveInStart(pData->hWaveHandle.In);
}
static void WinMMStopCapture(ALCdevice *pDevice)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
waveInStop(pData->hWaveHandle.In);
}
static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
return RingBufferSize(pData->pRing);
}
static void WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
{
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
if(WinMMAvailableSamples(pDevice) >= lSamples)
ReadRingBuffer(pData->pRing, pBuffer, lSamples);
else
alcSetError(pDevice, ALC_INVALID_VALUE);
}
static BackendFuncs WinMMFuncs = {
WinMMOpenPlayback,
WinMMClosePlayback,
WinMMResetPlayback,
WinMMStopPlayback,
WinMMOpenCapture,
WinMMCloseCapture,
WinMMStartCapture,
WinMMStopCapture,
WinMMCaptureSamples,
WinMMAvailableSamples
};
void alcWinMMInit(BackendFuncs *FuncList)
{
*FuncList = WinMMFuncs;
}
void alcWinMMDeinit()
{
ALuint lLoop;
for(lLoop = 0;lLoop < NumPlaybackDevices;lLoop++)
free(PlaybackDeviceList[lLoop]);
free(PlaybackDeviceList);
PlaybackDeviceList = NULL;
NumPlaybackDevices = 0;
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
free(CaptureDeviceList[lLoop]);
free(CaptureDeviceList);
CaptureDeviceList = NULL;
NumCaptureDevices = 0;
}
void alcWinMMProbe(int type)
{
ALuint i;
if(type == DEVICE_PROBE)
{
ProbePlaybackDevices();
if(NumPlaybackDevices > 0)
AppendDeviceList(woDefault);
}
else if(type == ALL_DEVICE_PROBE)
{
ProbePlaybackDevices();
if(NumPlaybackDevices > 0)
AppendAllDeviceList(woDefault);
for(i = 0;i < NumPlaybackDevices;i++)
{
if(PlaybackDeviceList[i])
AppendAllDeviceList(PlaybackDeviceList[i]);
}
}
else if(type == CAPTURE_DEVICE_PROBE)
{
ProbeCaptureDevices();
for(i = 0;i < NumCaptureDevices;i++)
{
if(CaptureDeviceList[i])
AppendCaptureDeviceList(CaptureDeviceList[i]);
}
}
}

5
jni/OpenAL/Makefile Normal file
View File

@ -0,0 +1,5 @@
ROOTDIR = ../..
TARGET = System/OpenAL
DEPS =
include $(ROOTDIR)/library.mk

View File

@ -0,0 +1,63 @@
#ifndef _AL_AUXEFFECTSLOT_H_
#define _AL_AUXEFFECTSLOT_H_
#include "AL/al.h"
#include "alEffect.h"
#include "alFilter.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ALeffectState ALeffectState;
typedef struct ALeffectslot
{
ALeffect effect;
ALfp Gain;
ALboolean AuxSendAuto;
ALeffectState *EffectState;
ALfp WetBuffer[BUFFERSIZE];
ALfp ClickRemoval[1];
ALfp PendingClicks[1];
ALuint refcount;
// Index to itself
ALuint effectslot;
struct ALeffectslot *next;
} ALeffectslot;
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
struct ALeffectState {
ALvoid (*Destroy)(ALeffectState *State);
ALboolean (*DeviceUpdate)(ALeffectState *State, ALCdevice *Device);
ALvoid (*Update)(ALeffectState *State, ALCcontext *Context, const ALeffect *Effect);
ALvoid (*Process)(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfp *SamplesIn, ALfp (*SamplesOut)[MAXCHANNELS]);
};
ALeffectState *NoneCreate(void);
ALeffectState *EAXVerbCreate(void);
ALeffectState *VerbCreate(void);
ALeffectState *EchoCreate(void);
ALeffectState *ModulatorCreate(void);
#define ALEffect_Destroy(a) ((a)->Destroy((a)))
#define ALEffect_DeviceUpdate(a,b) ((a)->DeviceUpdate((a),(b)))
#define ALEffect_Update(a,b,c) ((a)->Update((a),(b),(c)))
#define ALEffect_Process(a,b,c,d,e) ((a)->Process((a),(b),(c),(d),(e)))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,98 @@
#ifndef _AL_BUFFER_H_
#define _AL_BUFFER_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Input formats (some are currently theoretical) */
enum UserFmtType {
UserFmtByte, /* AL_BYTE */
UserFmtUByte, /* AL_UNSIGNED_BYTE */
UserFmtShort, /* AL_SHORT */
UserFmtUShort, /* AL_UNSIGNED_SHORT */
UserFmtInt, /* AL_INT */
UserFmtUInt, /* AL_UNSIGNED_INT */
UserFmtFloat, /* AL_FLOAT */
UserFmtDouble, /* AL_DOUBLE */
UserFmtMulaw, /* AL_MULAW */
UserFmtIMA4, /* AL_IMA4 */
};
enum UserFmtChannels {
UserFmtMono, /* AL_MONO */
UserFmtStereo, /* AL_STEREO */
UserFmtRear, /* AL_REAR */
UserFmtQuad, /* AL_QUAD */
UserFmtX51, /* AL_5POINT1 (WFX order) */
UserFmtX61, /* AL_6POINT1 (WFX order) */
UserFmtX71, /* AL_7POINT1 (WFX order) */
};
ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans,
enum UserFmtType *type);
ALuint BytesFromUserFmt(enum UserFmtType type);
ALuint ChannelsFromUserFmt(enum UserFmtChannels chans);
static __inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans,
enum UserFmtType type)
{
return ChannelsFromUserFmt(chans) * BytesFromUserFmt(type);
}
/* Storable formats */
enum FmtType {
FmtUByte = UserFmtUByte,
FmtShort = UserFmtShort,
FmtFloat = UserFmtFloat,
};
enum FmtChannels {
FmtMono = UserFmtMono,
FmtStereo = UserFmtStereo,
FmtRear = UserFmtRear,
FmtQuad = UserFmtQuad,
FmtX51 = UserFmtX51,
FmtX61 = UserFmtX61,
FmtX71 = UserFmtX71,
};
ALboolean DecomposeFormat(ALenum format, enum FmtChannels *chans, enum FmtType *type);
ALuint BytesFromFmt(enum FmtType type);
ALuint ChannelsFromFmt(enum FmtChannels chans);
static __inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type)
{
return ChannelsFromFmt(chans) * BytesFromFmt(type);
}
typedef struct ALbuffer
{
ALvoid *data;
ALsizei size;
ALsizei Frequency;
enum FmtChannels FmtChannels;
enum FmtType FmtType;
enum UserFmtChannels OriginalChannels;
enum UserFmtType OriginalType;
ALsizei OriginalSize;
ALsizei OriginalAlign;
ALsizei LoopStart;
ALsizei LoopEnd;
ALuint refcount; // Number of sources using this buffer (deletion can only occur when this is 0)
// Index to itself
ALuint buffer;
} ALbuffer;
ALvoid ReleaseALBuffers(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,33 @@
#ifndef _AL_DATABUFFER_H_
#define _AL_DATABUFFER_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
#define UNMAPPED 0
#define MAPPED 1
typedef struct ALdatabuffer
{
ALubyte *data;
ALintptrEXT size;
ALenum state;
ALenum usage;
/* Index to self */
ALuint databuffer;
struct ALdatabuffer *next;
} ALdatabuffer;
ALvoid ReleaseALDatabuffers(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,83 @@
// NOTE: The effect structure is getting too large, it may be a good idea to
// start using a union or another form of unified storage.
#ifndef _AL_EFFECT_H_
#define _AL_EFFECT_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
EAXREVERB = 0,
REVERB,
ECHO,
MODULATOR,
MAX_EFFECTS
};
extern ALboolean DisabledEffects[MAX_EFFECTS];
typedef struct ALeffect
{
// Effect type (AL_EFFECT_NULL, ...)
ALenum type;
struct {
// Shared Reverb Properties
ALfp Density;
ALfp Diffusion;
ALfp Gain;
ALfp GainHF;
ALfp DecayTime;
ALfp DecayHFRatio;
ALfp ReflectionsGain;
ALfp ReflectionsDelay;
ALfp LateReverbGain;
ALfp LateReverbDelay;
ALfp AirAbsorptionGainHF;
ALfp RoomRolloffFactor;
ALboolean DecayHFLimit;
// Additional EAX Reverb Properties
ALfp GainLF;
ALfp DecayLFRatio;
ALfp ReflectionsPan[3];
ALfp LateReverbPan[3];
ALfp EchoTime;
ALfp EchoDepth;
ALfp ModulationTime;
ALfp ModulationDepth;
ALfp HFReference;
ALfp LFReference;
} Reverb;
struct {
ALfp Delay;
ALfp LRDelay;
ALfp Damping;
ALfp Feedback;
ALfp Spread;
} Echo;
struct {
ALfp Frequency;
ALfp HighPassCutoff;
ALint Waveform;
} Modulator;
// Index to itself
ALuint effect;
} ALeffect;
ALvoid ReleaseALEffects(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,17 @@
#ifndef _AL_ERROR_H_
#define _AL_ERROR_H_
#include "AL/al.h"
#include "AL/alc.h"
#ifdef __cplusplus
extern "C" {
#endif
ALvoid alSetError(ALCcontext *Context, ALenum errorCode);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,139 @@
#ifndef _AL_FILTER_H_
#define _AL_FILTER_H_
#include "AL/al.h"
#include "alu.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
ALfp coeff;
#ifndef _MSC_VER
ALfp history[0];
#else
ALfp history[1];
#endif
} FILTER;
static __inline ALfp lpFilter4P(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;
output = output + ALfpMult((history[1]-output),a);
history[1] = output;
output = output + ALfpMult((history[2]-output),a);
history[2] = output;
output = output + ALfpMult((history[3]-output),a);
history[3] = output;
return output;
}
static __inline ALfp lpFilter2P(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;
output = output + ALfpMult((history[1]-output),a);
history[1] = output;
return output;
}
static __inline ALfp lpFilter1P(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 output;
}
static __inline ALfp lpFilter4PC(const FILTER *iir, ALuint offset, ALfp input)
{
const ALfp *history = &iir->history[offset];
ALfp a = iir->coeff;
ALfp output = input;
output = output + ALfpMult((history[0]-output),a);
output = output + ALfpMult((history[1]-output),a);
output = output + ALfpMult((history[2]-output),a);
output = output + ALfpMult((history[3]-output),a);
return output;
}
static __inline ALfp lpFilter2PC(const FILTER *iir, ALuint offset, ALfp input)
{
const ALfp *history = &iir->history[offset];
ALfp a = iir->coeff;
ALfp output = input;
output = output + ALfpMult((history[0]-output),a);
output = output + ALfpMult((history[1]-output),a);
return output;
}
static __inline ALfp lpFilter1PC(FILTER *iir, ALuint offset, ALfp input)
{
const ALfp *history = &iir->history[offset];
ALfp a = iir->coeff;
ALfp output = input;
output = output + ALfpMult((history[0]-output),a);
return output;
}
/* Calculates the low-pass filter coefficient given the pre-scaled gain and
* cos(w) value. Note that g should be pre-scaled (sqr(gain) for one-pole,
* sqrt(gain) for four-pole, etc) */
static __inline ALfp lpCoeffCalc(ALfp g, ALfp cw)
{
ALfp a = int2ALfp(0);
/* Be careful with gains < 0.01, as that causes the coefficient
* head towards 1, which will flatten the signal */
g = __max(g, float2ALfp(0.01f));
if(g < float2ALfp(0.9999f)) /* 1-epsilon */ {
ALfp tmp; tmp = ALfpMult(ALfpMult(int2ALfp(2),g),(int2ALfp(1)-cw)) - ALfpMult(ALfpMult(g,g),(int2ALfp(1) - ALfpMult(cw,cw)));
a = ALfpDiv((int2ALfp(1) - ALfpMult(g,cw) - aluSqrt(tmp)), (int2ALfp(1) - g));
}
return a;
}
typedef struct ALfilter
{
// Filter type (AL_FILTER_NULL, ...)
ALenum type;
ALfp Gain;
ALfp GainHF;
// Index to itself
ALuint filter;
} ALfilter;
ALvoid ReleaseALFilters(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,24 @@
#ifndef _AL_LISTENER_H_
#define _AL_LISTENER_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ALlistener_struct
{
ALfp Position[3];
ALfp Velocity[3];
ALfp Forward[3];
ALfp Up[3];
ALfp Gain;
ALfp MetersPerUnit;
} ALlistener;
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,500 @@
#ifndef AL_MAIN_H
#define AL_MAIN_H
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef HAVE_FENV_H
#include <fenv.h>
#endif
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#ifndef AL_EXT_sample_buffer_object
#define AL_EXT_sample_buffer_object 1
typedef ptrdiff_t ALintptrEXT;
typedef ptrdiff_t ALsizeiptrEXT;
#define AL_SAMPLE_SOURCE_EXT 0x1040
#define AL_SAMPLE_SINK_EXT 0x1041
#define AL_READ_ONLY_EXT 0x1042
#define AL_WRITE_ONLY_EXT 0x1043
#define AL_READ_WRITE_EXT 0x1044
#define AL_STREAM_WRITE_EXT 0x1045
#define AL_STREAM_READ_EXT 0x1046
#define AL_STREAM_COPY_EXT 0x1047
#define AL_STATIC_WRITE_EXT 0x1048
#define AL_STATIC_READ_EXT 0x1049
#define AL_STATIC_COPY_EXT 0x104A
#define AL_DYNAMIC_WRITE_EXT 0x104B
#define AL_DYNAMIC_READ_EXT 0x104C
#define AL_DYNAMIC_COPY_EXT 0x104D
typedef ALvoid (AL_APIENTRY*PFNALGENDATABUFFERSEXTPROC)(ALsizei n,ALuint *puiBuffers);
typedef ALvoid (AL_APIENTRY*PFNALDELETEDATABUFFERSEXTPROC)(ALsizei n, const ALuint *puiBuffers);
typedef ALboolean (AL_APIENTRY*PFNALISDATABUFFEREXTPROC)(ALuint uiBuffer);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERDATAEXTPROC)(ALuint buffer,const ALvoid *data,ALsizeiptrEXT size,ALenum usage);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALintptrEXT start, ALsizeiptrEXT length, const ALvoid *);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALintptrEXT start, ALsizeiptrEXT length, ALvoid *);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat flValue);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, const ALfloat* flValues);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint lValue);
typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, const ALint* plValues);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat *pflValue);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, ALfloat* pflValues);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint *plValue);
typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, ALint* plValues);
typedef ALvoid (AL_APIENTRY*PFNALSELECTDATABUFFEREXTPROC)(ALenum target, ALuint uiBuffer);
typedef ALvoid* (AL_APIENTRY*PFNALMAPDATABUFFEREXTPROC)(ALuint uiBuffer, ALintptrEXT start, ALsizeiptrEXT length, ALenum access);
typedef ALvoid (AL_APIENTRY*PFNALUNMAPDATABUFFEREXTPROC)(ALuint uiBuffer);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers);
AL_API ALvoid AL_APIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers);
AL_API ALboolean AL_APIENTRY alIsDatabufferEXT(ALuint uiBuffer);
AL_API ALvoid AL_APIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizeiptrEXT size,ALenum usage);
AL_API ALvoid AL_APIENTRY alDatabufferSubDataEXT(ALuint buffer, ALintptrEXT start, ALsizeiptrEXT length, const ALvoid *data);
AL_API ALvoid AL_APIENTRY alGetDatabufferSubDataEXT(ALuint buffer, ALintptrEXT start, ALsizeiptrEXT length, ALvoid *data);
AL_API ALvoid AL_APIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues);
AL_API ALvoid AL_APIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue);
AL_API ALvoid AL_APIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues);
AL_API ALvoid AL_APIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues);
AL_API ALvoid AL_APIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue);
AL_API ALvoid AL_APIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues);
AL_API ALvoid AL_APIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer);
AL_API ALvoid* AL_APIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALintptrEXT start, ALsizeiptrEXT length, ALenum access);
AL_API ALvoid AL_APIENTRY alUnmapDatabufferEXT(ALuint uiBuffer);
#endif
#endif
#if defined(HAVE_STDINT_H)
#include <stdint.h>
typedef int64_t ALint64;
typedef uint64_t ALuint64;
#elif defined(HAVE___INT64)
typedef __int64 ALint64;
typedef unsigned __int64 ALuint64;
#elif (SIZEOF_LONG == 8)
typedef long ALint64;
typedef unsigned long ALuint64;
#elif (SIZEOF_LONG_LONG == 8)
typedef long long ALint64;
typedef unsigned long long ALuint64;
#endif
#ifdef HAVE_GCC_FORMAT
#define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
#else
#define PRINTF_STYLE(x, y)
#endif
#ifdef _WIN32
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
typedef DWORD tls_type;
#define tls_create(x) (*(x) = TlsAlloc())
#define tls_delete(x) TlsFree((x))
#define tls_get(x) TlsGetValue((x))
#define tls_set(x, a) TlsSetValue((x), (a))
#else
#include <unistd.h>
#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>
#define IsBadWritePtr(a,b) ((a) == NULL && (b) != 0)
typedef pthread_key_t tls_type;
#define tls_create(x) pthread_key_create((x), NULL)
#define tls_delete(x) pthread_key_delete((x))
#define tls_get(x) pthread_getspecific((x))
#define tls_set(x, a) pthread_setspecific((x), (a))
typedef pthread_mutex_t CRITICAL_SECTION;
static __inline void EnterCriticalSection(CRITICAL_SECTION *cs)
{
int ret;
ret = pthread_mutex_lock(cs);
assert(ret == 0);
}
static __inline void LeaveCriticalSection(CRITICAL_SECTION *cs)
{
int ret;
ret = pthread_mutex_unlock(cs);
assert(ret == 0);
}
static __inline void InitializeCriticalSection(CRITICAL_SECTION *cs)
{
pthread_mutexattr_t attrib;
int ret;
ret = pthread_mutexattr_init(&attrib);
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);
pthread_mutexattr_destroy(&attrib);
}
static __inline void DeleteCriticalSection(CRITICAL_SECTION *cs)
{
int ret;
ret = pthread_mutex_destroy(cs);
assert(ret == 0);
}
/* NOTE: This wrapper isn't quite accurate as it returns an ALuint, as opposed
* to the expected DWORD. Both are defined as unsigned 32-bit types, however.
* Additionally, Win32 is supposed to measure the time since Windows started,
* as opposed to the actual time. */
static __inline ALuint timeGetTime(void)
{
#if _POSIX_TIMERS > 0
struct timespec ts;
int ret = -1;
#if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK >= 0)
#if _POSIX_MONOTONIC_CLOCK == 0
static int hasmono = 0;
if(hasmono > 0 || (hasmono == 0 &&
(hasmono=sysconf(_SC_MONOTONIC_CLOCK)) > 0))
#endif
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
#endif
if(ret != 0)
ret = clock_gettime(CLOCK_REALTIME, &ts);
assert(ret == 0);
return ts.tv_nsec/1000000 + ts.tv_sec*1000;
#else
struct timeval tv;
int ret;
ret = gettimeofday(&tv, NULL);
assert(ret == 0);
return tv.tv_usec/1000 + tv.tv_sec*1000;
#endif
}
static __inline void Sleep(ALuint t)
{
struct timespec tv, rem;
tv.tv_nsec = (t*1000000)%1000000000;
tv.tv_sec = t/1000;
while(nanosleep(&tv, &rem) == -1 && errno == EINTR)
tv = rem;
}
#define min(x,y) (((x)<(y))?(x):(y))
#define max(x,y) (((x)>(y))?(x):(y))
#endif
#include "alListener.h"
#include "alu.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SWMIXER_OUTPUT_RATE 44100
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
#define AIRABSORBGAINDBHF (-0.05f)
#define LOWPASSFREQCUTOFF (5000)
#define DEFAULT_HEAD_DAMPEN (0.25f)
// Find the next power-of-2 for non-power-of-2 numbers.
static __inline ALuint NextPowerOf2(ALuint value)
{
ALuint powerOf2 = 1;
if(value)
{
value--;
while(value)
{
value >>= 1;
powerOf2 <<= 1;
}
}
return powerOf2;
}
typedef struct {
ALCboolean (*OpenPlayback)(ALCdevice*, const ALCchar*);
void (*ClosePlayback)(ALCdevice*);
ALCboolean (*ResetPlayback)(ALCdevice*);
void (*StopPlayback)(ALCdevice*);
ALCboolean (*OpenCapture)(ALCdevice*, const ALCchar*);
void (*CloseCapture)(ALCdevice*);
void (*StartCapture)(ALCdevice*);
void (*StopCapture)(ALCdevice*);
void (*CaptureSamples)(ALCdevice*, void*, ALCuint);
ALCuint (*AvailableSamples)(ALCdevice*);
} BackendFuncs;
enum {
DEVICE_PROBE,
ALL_DEVICE_PROBE,
CAPTURE_DEVICE_PROBE
};
void alc_alsa_init(BackendFuncs *func_list);
void alc_alsa_deinit(void);
void alc_alsa_probe(int type);
void alc_oss_init(BackendFuncs *func_list);
void alc_oss_deinit(void);
void alc_oss_probe(int type);
void alc_solaris_init(BackendFuncs *func_list);
void alc_solaris_deinit(void);
void alc_solaris_probe(int type);
void alcDSoundInit(BackendFuncs *func_list);
void alcDSoundDeinit(void);
void alcDSoundProbe(int type);
void alcWinMMInit(BackendFuncs *FuncList);
void alcWinMMDeinit(void);
void alcWinMMProbe(int type);
void alc_pa_init(BackendFuncs *func_list);
void alc_pa_deinit(void);
void alc_pa_probe(int type);
void alc_wave_init(BackendFuncs *func_list);
void alc_wave_deinit(void);
void alc_wave_probe(int type);
void alc_pulse_init(BackendFuncs *func_list);
void alc_pulse_deinit(void);
void alc_pulse_probe(int type);
void alc_audiotrack_init(BackendFuncs *func_list);
void alc_audiotrack_deinit(void);
void alc_audiotrack_probe(int type);
void alc_opensles_init(BackendFuncs *func_list);
void alc_opensles_deinit(void);
void alc_opensles_probe(int type);
void alc_null_init(BackendFuncs *func_list);
void alc_null_deinit(void);
void alc_null_probe(int type);
typedef struct UIntMap {
struct {
ALuint key;
ALvoid *value;
} *array;
ALsizei size;
ALsizei maxsize;
} UIntMap;
void InitUIntMap(UIntMap *map);
void ResetUIntMap(UIntMap *map);
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value);
void RemoveUIntMapKey(UIntMap *map, ALuint key);
ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key);
/* Device formats */
enum DevFmtType {
DevFmtByte, /* AL_BYTE */
DevFmtUByte, /* AL_UNSIGNED_BYTE */
DevFmtShort, /* AL_SHORT */
DevFmtUShort, /* AL_UNSIGNED_SHORT */
DevFmtFloat, /* AL_FLOAT */
};
enum DevFmtChannels {
DevFmtMono, /* AL_MONO */
DevFmtStereo, /* AL_STEREO */
DevFmtQuad, /* AL_QUAD */
DevFmtX51, /* AL_5POINT1 */
DevFmtX61, /* AL_6POINT1 */
DevFmtX71, /* AL_7POINT1 */
};
ALuint BytesFromDevFmt(enum DevFmtType type);
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans);
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans,
enum DevFmtType type)
{
return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
}
struct ALCdevice_struct
{
ALCboolean Connected;
ALboolean IsCaptureDevice;
ALuint Frequency;
ALuint UpdateSize;
ALuint NumUpdates;
enum DevFmtChannels FmtChans;
enum DevFmtType FmtType;
ALCchar *szDeviceName;
ALCenum LastError;
// Maximum number of sources that can be created
ALuint MaxNoOfSources;
// Maximum number of slots that can be created
ALuint AuxiliaryEffectSlotMax;
ALCuint NumMonoSources;
ALCuint NumStereoSources;
ALuint NumAuxSends;
// Map of Buffers for this device
UIntMap BufferMap;
// Map of Effects for this device
UIntMap EffectMap;
// Map of Filters for this device
UIntMap FilterMap;
// Map of Databuffers for this device
UIntMap DatabufferMap;
// Stereo-to-binaural filter
struct bs2b *Bs2b;
ALCint Bs2bLevel;
// Simulated dampening from head occlusion
ALfp HeadDampen;
// Duplicate stereo sources on the side/rear channels
ALboolean DuplicateStereo;
// Dry path buffer mix
ALfp DryBuffer[BUFFERSIZE][MAXCHANNELS];
ALuint DevChannels[MAXCHANNELS];
ALfp ChannelMatrix[MAXCHANNELS][MAXCHANNELS];
Channel Speaker2Chan[MAXCHANNELS];
ALfp PanningLUT[MAXCHANNELS * LUT_NUM];
ALuint NumChan;
ALfp ClickRemoval[MAXCHANNELS];
ALfp PendingClicks[MAXCHANNELS];
// Contexts created on this device
ALCcontext **Contexts;
ALuint NumContexts;
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use
ALCdevice *next;
};
#define ALCdevice_OpenPlayback(a,b) ((a)->Funcs->OpenPlayback((a), (b)))
#define ALCdevice_ClosePlayback(a) ((a)->Funcs->ClosePlayback((a)))
#define ALCdevice_ResetPlayback(a) ((a)->Funcs->ResetPlayback((a)))
#define ALCdevice_StopPlayback(a) ((a)->Funcs->StopPlayback((a)))
#define ALCdevice_OpenCapture(a,b) ((a)->Funcs->OpenCapture((a), (b)))
#define ALCdevice_CloseCapture(a) ((a)->Funcs->CloseCapture((a)))
#define ALCdevice_StartCapture(a) ((a)->Funcs->StartCapture((a)))
#define ALCdevice_StopCapture(a) ((a)->Funcs->StopCapture((a)))
#define ALCdevice_CaptureSamples(a,b,c) ((a)->Funcs->CaptureSamples((a), (b), (c)))
#define ALCdevice_AvailableSamples(a) ((a)->Funcs->AvailableSamples((a)))
struct ALCcontext_struct
{
ALlistener Listener;
UIntMap SourceMap;
UIntMap EffectSlotMap;
struct ALdatabuffer *SampleSource;
struct ALdatabuffer *SampleSink;
ALenum LastError;
ALboolean Suspended;
ALenum DistanceModel;
ALboolean SourceDistanceModel;
ALfp DopplerFactor;
ALfp DopplerVelocity;
ALfp flSpeedOfSound;
struct ALsource **ActiveSources;
ALsizei ActiveSourceCount;
ALsizei MaxActiveSources;
ALCdevice *Device;
const ALCchar *ExtensionList;
ALCcontext *next;
};
void AppendDeviceList(const ALCchar *name);
void AppendAllDeviceList(const ALCchar *name);
void AppendCaptureDeviceList(const ALCchar *name);
ALCvoid alcSetError(ALCdevice *device, ALenum errorCode);
ALCvoid SuspendContext(ALCcontext *context);
ALCvoid ProcessContext(ALCcontext *context);
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
ALuint StopThread(ALvoid *thread);
ALCcontext *GetContextSuspended(void);
typedef struct RingBuffer RingBuffer;
RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
void DestroyRingBuffer(RingBuffer *ring);
ALsizei RingBufferSize(RingBuffer *ring);
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
void ReadALConfig(void);
void FreeALConfig(void);
int ConfigValueExists(const char *blockName, const char *keyName);
const char *GetConfigValue(const char *blockName, const char *keyName, const char *def);
int GetConfigValueInt(const char *blockName, const char *keyName, int def);
float GetConfigValueFloat(const char *blockName, const char *keyName, float def);
int GetConfigValueBool(const char *blockName, const char *keyName, int def);
void SetRTPriority(void);
void SetDefaultChannelOrder(ALCdevice *device);
void SetDefaultWFXChannelOrder(ALCdevice *device);
void al_print(const char *fname, unsigned int line, const char *fmt, ...)
PRINTF_STYLE(3,4);
#define AL_PRINT(...) al_print(__FILE__, __LINE__, __VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,121 @@
#ifndef _AL_SOURCE_H_
#define _AL_SOURCE_H_
#define MAX_SENDS 4
#include "alFilter.h"
#include "alu.h"
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
POINT_RESAMPLER = 0,
LINEAR_RESAMPLER,
CUBIC_RESAMPLER,
RESAMPLER_MAX,
RESAMPLER_MIN = -1,
RESAMPLER_DEFAULT = LINEAR_RESAMPLER
} resampler_t;
extern resampler_t DefaultResampler;
extern const ALsizei ResamplerPadding[RESAMPLER_MAX];
extern const ALsizei ResamplerPrePadding[RESAMPLER_MAX];
typedef struct ALbufferlistitem
{
struct ALbuffer *buffer;
struct ALbufferlistitem *next;
struct ALbufferlistitem *prev;
} ALbufferlistitem;
typedef struct ALsource
{
ALfp flPitch;
ALfp flGain;
ALfp flOuterGain;
ALfp flMinGain;
ALfp flMaxGain;
ALfp flInnerAngle;
ALfp flOuterAngle;
ALfp flRefDistance;
ALfp flMaxDistance;
ALfp flRollOffFactor;
ALfp vPosition[3];
ALfp vVelocity[3];
ALfp vOrientation[3];
ALboolean bHeadRelative;
ALboolean bLooping;
ALenum DistanceModel;
resampler_t Resampler;
ALenum state;
ALuint position;
ALuint position_fraction;
struct ALbuffer *Buffer;
ALbufferlistitem *queue; // Linked list of buffers in queue
ALuint BuffersInQueue; // Number of buffers in queue
ALuint BuffersPlayed; // Number of buffers played on this loop
ALfilter DirectFilter;
struct {
struct ALeffectslot *Slot;
ALfilter WetFilter;
} Send[MAX_SENDS];
ALboolean DryGainHFAuto;
ALboolean WetGainAuto;
ALboolean WetGainHFAuto;
ALfp OuterGainHF;
ALfp AirAbsorptionFactor;
ALfp RoomRolloffFactor;
ALfp DopplerFactor;
ALint lOffset;
ALint lOffsetType;
// Source Type (Static, Streaming, or Undetermined)
ALint lSourceType;
// Current target parameters used for mixing
ALboolean NeedsUpdate;
struct {
ALint Step;
/* A mixing matrix. First subscript is the channel number of the input
* data (regardless of channel configuration) and the second is the
* channel target (eg. FRONT_LEFT) */
ALfp DryGains[MAXCHANNELS][MAXCHANNELS];
FILTER iirFilter;
ALfp history[MAXCHANNELS*2];
struct {
ALfp WetGain;
FILTER iirFilter;
ALfp history[MAXCHANNELS];
} Send[MAX_SENDS];
} Params;
ALvoid (*Update)(struct ALsource *self, const ALCcontext *context);
// Index to itself
ALuint source;
} ALsource;
#define ALsource_Update(s,a) ((s)->Update(s,a))
ALvoid ReleaseALSources(ALCcontext *Context);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,14 @@
#ifndef _AL_STATE_H_
#define _AL_STATE_H_
#include "AL/al.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,42 @@
#ifndef _AL_THUNK_H_
#define _AL_THUNK_H_
#include "config.h"
#include "AL/al.h"
#include "AL/alc.h"
#ifdef __cplusplus
extern "C" {
#endif
void alThunkInit(void);
void alThunkExit(void);
ALuint alThunkAddEntry(ALvoid *ptr);
void alThunkRemoveEntry(ALuint index);
ALvoid *alThunkLookupEntry(ALuint index);
#if (SIZEOF_VOIDP > SIZEOF_UINT)
#define ALTHUNK_INIT() alThunkInit()
#define ALTHUNK_EXIT() alThunkExit()
#define ALTHUNK_ADDENTRY(p) alThunkAddEntry(p)
#define ALTHUNK_REMOVEENTRY(i) alThunkRemoveEntry(i)
#define ALTHUNK_LOOKUPENTRY(i) alThunkLookupEntry(i)
#else
#define ALTHUNK_INIT()
#define ALTHUNK_EXIT()
#define ALTHUNK_ADDENTRY(p) ((ALuint)p)
#define ALTHUNK_REMOVEENTRY(i) ((ALvoid)i)
#define ALTHUNK_LOOKUPENTRY(i) ((ALvoid*)(i))
#endif // (SIZEOF_VOIDP > SIZEOF_INT)
#ifdef __cplusplus
}
#endif
#endif //_AL_THUNK_H_

View File

@ -0,0 +1,135 @@
#ifndef _ALU_H_
#define _ALU_H_
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include <limits.h>
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846 /* pi */
#define M_PI_2 1.57079632679489661923 /* pi/2 */
#endif
#ifdef HAVE_POWF
#define aluPow(x,y) (float2ALfp(powf(ALfp2float(x), ALfp2float(y))))
#else
#define aluPow(x,y) (float2ALfp((float)pow((double)ALfp2float(x), (double)ALfp2float(y))))
#endif
#ifdef HAVE_SQRTF
#define aluSqrt(x) (float2ALfp(sqrtf(ALfp2float(x))))
#else
#define aluSqrt(x) (float2ALfp((float)sqrt((double)ALfp2float(x))))
#endif
#ifdef HAVE_ACOSF
#define aluAcos(x) (float2ALfp(acosf(ALfp2float(x))))
#else
#define aluAcos(x) (float2ALfp((float)acos((double)ALfp2float(x))))
#endif
#ifdef HAVE_ATANF
#define aluAtan(x) (float2ALfp(atanf(ALfp2float(x))))
#else
#define aluAtan(x) (float2ALfp((float)atan((double)ALfp2float(x))))
#endif
#ifdef HAVE_FABSF
#define aluFabs(x) (float2ALfp(fabsf(ALfp2float(x))))
#else
#define aluFabs(x) (float2ALfp((float)fabs((double)ALfp2float(x))))
#endif
// FIXME make this better
#if defined(max) && !defined(__max)
#define __max(x,y) float2ALfp(max(ALfp2float(x),ALfp2float(y)))
#endif
#if defined(min) && !defined(__min)
#define __min(x,y) float2ALfp(min(ALfp2float(x),ALfp2float(y)))
#endif
#define QUADRANT_NUM 128
#define LUT_NUM (4 * QUADRANT_NUM)
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
FRONT_LEFT = 0,
FRONT_RIGHT,
FRONT_CENTER,
LFE,
BACK_LEFT,
BACK_RIGHT,
BACK_CENTER,
SIDE_LEFT,
SIDE_RIGHT,
MAXCHANNELS
} Channel;
#define BUFFERSIZE 4096
#define FRACTIONBITS (14)
#define FRACTIONONE (1<<FRACTIONBITS)
#define FRACTIONMASK (FRACTIONONE-1)
/* Size for temporary stack storage of buffer data. Larger values need more
* stack, while smaller values may need more iterations. The value needs to be
* a sensible size, however, as it constrains the max stepping value used for
* mixing.
* The mixer requires being able to do two samplings per mixing loop. A 16KB
* buffer can hold 512 sample frames for a 7.1 float buffer. With the cubic
* resampler (which requires 3 padding sample frames), this limits the maximum
* step to about 508. This means that buffer_freq*source_pitch cannot exceed
* device_freq*508 for an 8-channel 32-bit buffer. */
#ifndef STACK_DATA_SIZE
#define STACK_DATA_SIZE 16384
#endif
//FIXME this code assumes ALfp==ALdfp
static __inline ALdfp lerp(ALdfp val1, ALdfp val2, ALdfp mu)
{
ALdfp retval;
retval = val1 + ALfpMult((val2-val1),mu);
return retval;
}
static __inline ALdfp cubic(ALdfp val0, ALdfp val1, ALdfp val2, ALdfp val3, ALdfp mu)
{
ALdfp retval;
ALdfp mu2;mu2 = ALfpMult(mu,mu);
ALdfp a0;a0 = ALfpMult(float2ALfp(-0.5f),val0) + ALfpMult(float2ALfp( 1.5f),val1) + ALfpMult(float2ALfp(-1.5f),val2) + ALfpMult(float2ALfp( 0.5), val3);
ALdfp a1;a1 = val0 + ALfpMult(float2ALfp(-2.5f),val1) + ALfpMult(float2ALfp( 2.0), val2) + ALfpMult(float2ALfp(-0.5f),val3);
ALdfp a2;a2 = ALfpMult(float2ALfp(-0.5f),val0) + ALfpMult(float2ALfp( 0.5), val2);
ALdfp a3;a3 = val1;
retval = ALfpMult(ALfpMult(a0,mu),mu2) + ALfpMult(a1,mu2) + ALfpMult(a2,mu) + a3;
return retval;
}
struct ALsource;
ALvoid aluInitPanning(ALCdevice *Device);
ALint aluCart2LUTpos(ALfp re, ALfp im);
ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo);
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
ALvoid aluHandleDisconnect(ALCdevice *device);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,111 @@
/*-
* Copyright (c) 2005 Boris Mikhaylov
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef BS2B_H
#define BS2B_H
#include "AL/al.h"
/* Number of crossfeed levels */
#define BS2B_CLEVELS 3
/* Normal crossfeed levels */
#define BS2B_HIGH_CLEVEL 3
#define BS2B_MIDDLE_CLEVEL 2
#define BS2B_LOW_CLEVEL 1
/* Easy crossfeed levels */
#define BS2B_HIGH_ECLEVEL BS2B_HIGH_CLEVEL + BS2B_CLEVELS
#define BS2B_MIDDLE_ECLEVEL BS2B_MIDDLE_CLEVEL + BS2B_CLEVELS
#define BS2B_LOW_ECLEVEL BS2B_LOW_CLEVEL + BS2B_CLEVELS
/* Default crossfeed levels */
#define BS2B_DEFAULT_CLEVEL BS2B_HIGH_ECLEVEL
/* Default sample rate (Hz) */
#define BS2B_DEFAULT_SRATE 44100
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct bs2b {
int level; /* Crossfeed level */
int srate; /* Sample rate (Hz) */
/* Lowpass IIR filter coefficients */
double a0_lo;
double b1_lo;
/* Highboost IIR filter coefficients */
double a0_hi;
double a1_hi;
double b1_hi;
/* Global gain against overloading */
double gain;
/* Buffer of last filtered sample.
* [0] - first channel, [1] - second channel
*/
struct t_last_sample {
double asis[2];
double lo[2];
double hi[2];
} last_sample;
};
/* Clear buffers and set new coefficients with new crossfeed level value.
* level - crossfeed level of *LEVEL values.
*/
void bs2b_set_level(struct bs2b *bs2b, int level);
/* Return current crossfeed level value */
int bs2b_get_level(struct bs2b *bs2b);
/* Clear buffers and set new coefficients with new sample rate value.
* srate - sample rate by Hz.
*/
void bs2b_set_srate(struct bs2b *bs2b, int srate);
/* Return current sample rate value */
int bs2b_get_srate(struct bs2b *bs2b);
/* Clear buffer */
void bs2b_clear(struct bs2b *bs2b);
/* Return 1 if buffer is clear */
int bs2b_is_clear(struct bs2b *bs2b);
/* Crossfeeds one stereo sample that are pointed by sample.
* [0] - first channel, [1] - second channel.
* Returns crossfided samle by sample pointer.
*/
/* sample points to floats */
void bs2b_cross_feed(struct bs2b *bs2b, ALfp *sample);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* BS2B_H */

View File

@ -0,0 +1,528 @@
/**
* 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 <math.h>
#include "AL/al.h"
#include "AL/alc.h"
#include "alMain.h"
#include "alAuxEffectSlot.h"
#include "alThunk.h"
#include "alError.h"
#include "alSource.h"
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect);
#define LookupEffectSlot(m, k) ((ALeffectslot*)LookupUIntMapKey(&(m), (k)))
#define LookupEffect(m, k) ((ALeffect*)LookupUIntMapKey(&(m), (k)))
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
{
ALCcontext *Context;
ALCdevice *Device;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
alSetError(Context, AL_INVALID_VALUE);
else if((ALuint)n > Device->AuxiliaryEffectSlotMax - Context->EffectSlotMap.size)
alSetError(Context, AL_INVALID_VALUE);
else
{
ALenum err;
ALsizei i, j;
i = 0;
while(i < n)
{
ALeffectslot *slot = calloc(1, sizeof(ALeffectslot));
if(!slot || !(slot->EffectState=NoneCreate()))
{
free(slot);
// We must have run out or memory
alSetError(Context, AL_OUT_OF_MEMORY);
alDeleteAuxiliaryEffectSlots(i, effectslots);
break;
}
slot->effectslot = (ALuint)ALTHUNK_ADDENTRY(slot);
err = InsertUIntMapEntry(&Context->EffectSlotMap,
slot->effectslot, slot);
if(err != AL_NO_ERROR)
{
ALTHUNK_REMOVEENTRY(slot->effectslot);
ALEffect_Destroy(slot->EffectState);
free(slot);
alSetError(Context, err);
alDeleteAuxiliaryEffectSlots(i, effectslots);
break;
}
effectslots[i++] = slot->effectslot;
slot->Gain = int2ALfp(1);
slot->AuxSendAuto = AL_TRUE;
for(j = 0;j < BUFFERSIZE;j++)
slot->WetBuffer[j] = int2ALfp(0);
for(j = 0;j < 1;j++)
{
slot->ClickRemoval[j] = int2ALfp(0);
slot->PendingClicks[j] = int2ALfp(0);
}
slot->refcount = 0;
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
{
ALCcontext *Context;
ALeffectslot *EffectSlot;
ALboolean SlotsValid = AL_FALSE;
ALsizei i;
Context = GetContextSuspended();
if(!Context) return;
if(n < 0)
alSetError(Context, AL_INVALID_VALUE);
else
{
SlotsValid = AL_TRUE;
// Check that all effectslots are valid
for(i = 0;i < n;i++)
{
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
{
alSetError(Context, AL_INVALID_NAME);
SlotsValid = AL_FALSE;
break;
}
else if(EffectSlot->refcount > 0)
{
alSetError(Context, AL_INVALID_NAME);
SlotsValid = AL_FALSE;
break;
}
}
}
if(SlotsValid)
{
// All effectslots are valid
for(i = 0;i < n;i++)
{
// Recheck that the effectslot is valid, because there could be duplicated names
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslots[i])) == NULL)
continue;
ALEffect_Destroy(EffectSlot->EffectState);
RemoveUIntMapKey(&Context->EffectSlotMap, EffectSlot->effectslot);
ALTHUNK_REMOVEENTRY(EffectSlot->effectslot);
memset(EffectSlot, 0, sizeof(ALeffectslot));
free(EffectSlot);
}
}
ProcessContext(Context);
}
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
{
ALCcontext *Context;
ALboolean result;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
result = (LookupEffectSlot(Context->EffectSlotMap, effectslot) ?
AL_TRUE : AL_FALSE);
ProcessContext(Context);
return result;
}
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
{
ALCdevice *Device;
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
ALeffectslot *EffectSlot;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_EFFECT: {
ALeffect *effect = NULL;
if(iValue == 0 ||
(effect=LookupEffect(Device->EffectMap, iValue)) != NULL)
{
InitializeEffect(Context, EffectSlot, effect);
updateSources = AL_TRUE;
}
else
alSetError(Context, AL_INVALID_VALUE);
} break;
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
if(iValue == AL_TRUE || iValue == AL_FALSE)
{
EffectSlot->AuxSendAuto = iValue;
updateSources = AL_TRUE;
}
else
alSetError(Context, AL_INVALID_VALUE);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
// Force updating the sources that use this slot, since it affects the
// sending parameters
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
ALuint i;
for(i = 0;i < Device->NumAuxSends;i++)
{
if(!source->Send[i].Slot ||
source->Send[i].Slot->effectslot != effectslot)
continue;
source->NeedsUpdate = AL_TRUE;
break;
}
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_EFFECT:
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flArg)
{
ALCcontext *Context;
ALeffectslot *EffectSlot;
ALfp flValue = float2ALfp(flArg);
Context = GetContextSuspended();
if(!Context) return;
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_GAIN:
if(flValue >= int2ALfp(0) && flValue <= int2ALfp(1))
EffectSlot->Gain = flValue;
else
alSetError(Context, AL_INVALID_VALUE);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_GAIN:
alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
{
ALCcontext *Context;
ALeffectslot *EffectSlot;
Context = GetContextSuspended();
if(!Context) return;
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_EFFECT:
*piValue = EffectSlot->effect.effect;
break;
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
*piValue = EffectSlot->AuxSendAuto;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_EFFECT:
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
alGetAuxiliaryEffectSloti(effectslot, param, piValues);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
{
ALCcontext *Context;
ALeffectslot *EffectSlot;
Context = GetContextSuspended();
if(!Context) return;
if((EffectSlot=LookupEffectSlot(Context->EffectSlotMap, effectslot)) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_GAIN:
*pflValue = ALfp2float(EffectSlot->Gain);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(LookupEffectSlot(Context->EffectSlotMap, effectslot) != NULL)
{
switch(param)
{
case AL_EFFECTSLOT_GAIN:
alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
static ALvoid NoneDestroy(ALeffectState *State)
{ free(State); }
static ALboolean NoneDeviceUpdate(ALeffectState *State, ALCdevice *Device)
{
return AL_TRUE;
(void)State;
(void)Device;
}
static ALvoid NoneUpdate(ALeffectState *State, ALCcontext *Context, const ALeffect *Effect)
{
(void)State;
(void)Context;
(void)Effect;
}
static ALvoid NoneProcess(ALeffectState *State, const ALeffectslot *Slot, ALuint SamplesToDo, const ALfp *SamplesIn, ALfp (*SamplesOut)[MAXCHANNELS])
{
(void)State;
(void)Slot;
(void)SamplesToDo;
(void)SamplesIn;
(void)SamplesOut;
}
ALeffectState *NoneCreate(void)
{
ALeffectState *state;
state = calloc(1, sizeof(*state));
if(!state)
return NULL;
state->Destroy = NoneDestroy;
state->DeviceUpdate = NoneDeviceUpdate;
state->Update = NoneUpdate;
state->Process = NoneProcess;
return state;
}
static ALvoid InitializeEffect(ALCcontext *Context, ALeffectslot *EffectSlot, ALeffect *effect)
{
if(EffectSlot->effect.type != (effect?effect->type:AL_EFFECT_NULL))
{
ALeffectState *NewState = NULL;
if(!effect || effect->type == AL_EFFECT_NULL)
NewState = NoneCreate();
else if(effect->type == AL_EFFECT_EAXREVERB)
NewState = EAXVerbCreate();
else if(effect->type == AL_EFFECT_REVERB)
NewState = VerbCreate();
else if(effect->type == AL_EFFECT_ECHO)
NewState = EchoCreate();
else if(effect->type == AL_EFFECT_RING_MODULATOR)
NewState = ModulatorCreate();
/* No new state? An error occured.. */
if(NewState == NULL ||
ALEffect_DeviceUpdate(NewState, Context->Device) == AL_FALSE)
{
if(NewState)
ALEffect_Destroy(NewState);
alSetError(Context, AL_OUT_OF_MEMORY);
return;
}
if(EffectSlot->EffectState)
ALEffect_Destroy(EffectSlot->EffectState);
EffectSlot->EffectState = NewState;
}
if(!effect)
memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
else
memcpy(&EffectSlot->effect, effect, sizeof(*effect));
ALEffect_Update(EffectSlot->EffectState, Context, effect);
}
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
{
ALsizei pos;
for(pos = 0;pos < Context->EffectSlotMap.size;pos++)
{
ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
Context->EffectSlotMap.array[pos].value = NULL;
// Release effectslot structure
ALEffect_Destroy(temp->EffectState);
ALTHUNK_REMOVEENTRY(temp->effectslot);
memset(temp, 0, sizeof(ALeffectslot));
free(temp);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,648 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2007 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "alMain.h"
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "alError.h"
#include "alDatabuffer.h"
#include "alThunk.h"
#define LookupDatabuffer(m, k) ((ALdatabuffer*)LookupUIntMapKey(&(m), (k)))
/*
* alGenDatabuffersEXT(ALsizei n, ALuint *puiBuffers)
*
* Generates n AL Databuffers, and stores the Databuffers Names in the array pointed to by puiBuffers
*/
AL_API ALvoid AL_APIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers)
{
ALCcontext *Context;
ALsizei i=0;
Context = GetContextSuspended();
if(!Context) return;
/* Check that we are actually generation some Databuffers */
if(n < 0 || IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
alSetError(Context, AL_INVALID_VALUE);
else
{
ALCdevice *device = Context->Device;
ALenum err;
/* Create all the new Databuffers */
while(i < n)
{
ALdatabuffer *buffer = calloc(1, sizeof(ALdatabuffer));
if(!buffer)
{
alSetError(Context, AL_OUT_OF_MEMORY);
alDeleteDatabuffersEXT(i, puiBuffers);
break;
}
buffer->databuffer = ALTHUNK_ADDENTRY(buffer);
err = InsertUIntMapEntry(&device->DatabufferMap,
buffer->databuffer, buffer);
if(err != AL_NO_ERROR)
{
ALTHUNK_REMOVEENTRY(buffer->databuffer);
memset(buffer, 0, sizeof(ALdatabuffer));
free(buffer);
alSetError(Context, err);
alDeleteDatabuffersEXT(i, puiBuffers);
break;
}
puiBuffers[i++] = buffer->databuffer;
buffer->state = UNMAPPED;
}
}
ProcessContext(Context);
}
/*
* alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
*
* Deletes the n AL Databuffers pointed to by puiBuffers
*/
AL_API ALvoid AL_APIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *buffers)
{
ALCcontext *Context;
ALCdevice *device;
ALdatabuffer *ALBuf;
ALboolean Failed;
ALsizei i;
Context = GetContextSuspended();
if(!Context) return;
/* Check we are actually Deleting some Databuffers */
Failed = AL_TRUE;
device = Context->Device;
if(n < 0)
alSetError(Context, AL_INVALID_VALUE);
else
{
Failed = AL_FALSE;
/* Check that all the databuffers are valid and can actually be
* deleted */
for(i = 0;i < n;i++)
{
if(!buffers[i])
continue;
/* Check for valid Buffer ID */
if((ALBuf=LookupDatabuffer(device->DatabufferMap, buffers[i])) == NULL)
{
/* Invalid Databuffer */
alSetError(Context, AL_INVALID_NAME);
Failed = AL_TRUE;
break;
}
else if(ALBuf->state != UNMAPPED)
{
/* Databuffer still in use, cannot be deleted */
alSetError(Context, AL_INVALID_OPERATION);
Failed = AL_TRUE;
break;
}
}
}
/* If all the Databuffers were valid (and unmapped), then we can delete them */
if(!Failed)
{
for(i = 0;i < n;i++)
{
if((ALBuf=LookupDatabuffer(device->DatabufferMap, buffers[i])) == NULL)
continue;
if(ALBuf == Context->SampleSource)
Context->SampleSource = NULL;
if(ALBuf == Context->SampleSink)
Context->SampleSink = NULL;
// Release the memory used to store audio data
free(ALBuf->data);
// Release buffer structure
RemoveUIntMapKey(&device->DatabufferMap, ALBuf->databuffer);
ALTHUNK_REMOVEENTRY(ALBuf->databuffer);
memset(ALBuf, 0, sizeof(ALdatabuffer));
free(ALBuf);
}
}
ProcessContext(Context);
}
/*
* alIsDatabufferEXT(ALuint uiBuffer)
*
* Checks if ulBuffer is a valid Databuffer Name
*/
AL_API ALboolean AL_APIENTRY alIsDatabufferEXT(ALuint buffer)
{
ALCcontext *Context;
ALboolean result;
ALCdevice *device;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
device = Context->Device;
result = ((!buffer || LookupDatabuffer(device->DatabufferMap, buffer)) ?
AL_TRUE : AL_FALSE);
ProcessContext(Context);
return result;
}
/*
* alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
*
* Fill databuffer with data
*/
AL_API ALvoid AL_APIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizeiptrEXT size,ALenum usage)
{
ALCcontext *Context;
ALdatabuffer *ALBuf;
ALCdevice *Device;
ALvoid *temp;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((ALBuf=LookupDatabuffer(Device->DatabufferMap, buffer)) != NULL)
{
if(ALBuf->state == UNMAPPED)
{
if(usage == AL_STREAM_WRITE_EXT || usage == AL_STREAM_READ_EXT ||
usage == AL_STREAM_COPY_EXT || usage == AL_STATIC_WRITE_EXT ||
usage == AL_STATIC_READ_EXT || usage == AL_STATIC_COPY_EXT ||
usage == AL_DYNAMIC_WRITE_EXT || usage == AL_DYNAMIC_READ_EXT ||
usage == AL_DYNAMIC_COPY_EXT)
{
if(size >= 0)
{
/* (Re)allocate data */
temp = realloc(ALBuf->data, size);
if(temp)
{
ALBuf->data = temp;
ALBuf->size = size;
ALBuf->usage = usage;
if(data)
memcpy(ALBuf->data, data, size);
}
else
alSetError(Context, AL_OUT_OF_MEMORY);
}
else
alSetError(Context, AL_INVALID_VALUE);
}
else
alSetError(Context, AL_INVALID_ENUM);
}
else
alSetError(Context, AL_INVALID_OPERATION);
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alDatabufferSubDataEXT(ALuint uiBuffer, ALintptrEXT start, ALsizeiptrEXT length, const ALvoid *data)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if((pBuffer=LookupDatabuffer(Device->DatabufferMap, uiBuffer)) != NULL)
{
if(start >= 0 && length >= 0 && start+length <= pBuffer->size)
{
if(pBuffer->state == UNMAPPED)
memcpy(pBuffer->data+start, data, length);
else
alSetError(pContext, AL_INVALID_OPERATION);
}
else
alSetError(pContext, AL_INVALID_VALUE);
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetDatabufferSubDataEXT(ALuint uiBuffer, ALintptrEXT start, ALsizeiptrEXT length, ALvoid *data)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if((pBuffer=LookupDatabuffer(Device->DatabufferMap, uiBuffer)) != NULL)
{
if(start >= 0 && length >= 0 && start+length <= pBuffer->size)
{
if(pBuffer->state == UNMAPPED)
memcpy(data, pBuffer->data+start, length);
else
alSetError(pContext, AL_INVALID_OPERATION);
}
else
alSetError(pContext, AL_INVALID_VALUE);
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue)
{
ALCcontext *pContext;
ALCdevice *Device;
(void)flValue;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues)
{
ALCcontext *pContext;
ALCdevice *Device;
(void)flValues;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue)
{
ALCcontext *pContext;
ALCdevice *Device;
(void)lValue;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues)
{
ALCcontext *pContext;
ALCdevice *Device;
(void)plValues;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue)
{
ALCcontext *pContext;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValue)
{
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues)
{
ALCcontext *pContext;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValues)
{
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValue)
{
Device = pContext->Device;
if((pBuffer=LookupDatabuffer(Device->DatabufferMap, buffer)) != NULL)
{
switch(eParam)
{
case AL_SIZE:
*plValue = (ALint)pBuffer->size;
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues)
{
ALCcontext *pContext;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValues)
{
Device = pContext->Device;
if(LookupDatabuffer(Device->DatabufferMap, buffer) != NULL)
{
switch (eParam)
{
case AL_SIZE:
alGetDatabufferiEXT(buffer, eParam, plValues);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_NAME);
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer = NULL;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if(uiBuffer == 0 ||
(pBuffer=LookupDatabuffer(Device->DatabufferMap, uiBuffer)) != NULL)
{
if(target == AL_SAMPLE_SOURCE_EXT)
pContext->SampleSource = pBuffer;
else if(target == AL_SAMPLE_SINK_EXT)
pContext->SampleSink = pBuffer;
else
alSetError(pContext, AL_INVALID_VALUE);
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
AL_API ALvoid* AL_APIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALintptrEXT start, ALsizeiptrEXT length, ALenum access)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALvoid *ret = NULL;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return NULL;
Device = pContext->Device;
if((pBuffer=LookupDatabuffer(Device->DatabufferMap, uiBuffer)) != NULL)
{
if(start >= 0 && length >= 0 && start+length <= pBuffer->size)
{
if(access == AL_READ_ONLY_EXT || access == AL_WRITE_ONLY_EXT ||
access == AL_READ_WRITE_EXT)
{
if(pBuffer->state == UNMAPPED)
{
ret = pBuffer->data + start;
pBuffer->state = MAPPED;
}
else
alSetError(pContext, AL_INVALID_OPERATION);
}
else
alSetError(pContext, AL_INVALID_ENUM);
}
else
alSetError(pContext, AL_INVALID_VALUE);
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
return ret;
}
AL_API ALvoid AL_APIENTRY alUnmapDatabufferEXT(ALuint uiBuffer)
{
ALCcontext *pContext;
ALdatabuffer *pBuffer;
ALCdevice *Device;
pContext = GetContextSuspended();
if(!pContext) return;
Device = pContext->Device;
if((pBuffer=LookupDatabuffer(Device->DatabufferMap, uiBuffer)) != NULL)
{
if(pBuffer->state == MAPPED)
pBuffer->state = UNMAPPED;
else
alSetError(pContext, AL_INVALID_OPERATION);
}
else
alSetError(pContext, AL_INVALID_NAME);
ProcessContext(pContext);
}
/*
* ReleaseALDatabuffers()
*
* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
*/
ALvoid ReleaseALDatabuffers(ALCdevice *device)
{
ALsizei i;
for(i = 0;i < device->DatabufferMap.size;i++)
{
ALdatabuffer *temp = device->DatabufferMap.array[i].value;
device->DatabufferMap.array[i].value = NULL;
// Release buffer data
free(temp->data);
// Release Buffer structure
ALTHUNK_REMOVEENTRY(temp->databuffer);
memset(temp, 0, sizeof(ALdatabuffer));
free(temp);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 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 "alMain.h"
#include "AL/alc.h"
#include "alError.h"
AL_API ALenum AL_APIENTRY alGetError(ALvoid)
{
ALCcontext *Context;
ALenum errorCode;
Context = GetContextSuspended();
if(!Context) return AL_INVALID_OPERATION;
errorCode = Context->LastError;
Context->LastError = AL_NO_ERROR;
ProcessContext(Context);
return errorCode;
}
ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
{
if(Context->LastError == AL_NO_ERROR)
Context->LastError = errorCode;
}

View File

@ -0,0 +1,331 @@
/**
* 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 <string.h>
#include <ctype.h>
#include "alError.h"
#include "alMain.h"
#include "alFilter.h"
#include "alEffect.h"
#include "alAuxEffectSlot.h"
#include "alDatabuffer.h"
#include "alSource.h"
#include "alBuffer.h"
#include "AL/al.h"
#include "AL/alc.h"
typedef struct ALenums {
const ALchar *enumName;
ALenum value;
} ALenums;
static const ALenums enumeration[] = {
// Types
{ "AL_INVALID", AL_INVALID },
{ "AL_NONE", AL_NONE },
{ "AL_FALSE", AL_FALSE },
{ "AL_TRUE", AL_TRUE },
// Source and Listener Properties
{ "AL_SOURCE_RELATIVE", AL_SOURCE_RELATIVE },
{ "AL_CONE_INNER_ANGLE", AL_CONE_INNER_ANGLE },
{ "AL_CONE_OUTER_ANGLE", AL_CONE_OUTER_ANGLE },
{ "AL_PITCH", AL_PITCH },
{ "AL_POSITION", AL_POSITION },
{ "AL_DIRECTION", AL_DIRECTION },
{ "AL_VELOCITY", AL_VELOCITY },
{ "AL_LOOPING", AL_LOOPING },
{ "AL_BUFFER", AL_BUFFER },
{ "AL_GAIN", AL_GAIN },
{ "AL_MIN_GAIN", AL_MIN_GAIN },
{ "AL_MAX_GAIN", AL_MAX_GAIN },
{ "AL_ORIENTATION", AL_ORIENTATION },
{ "AL_REFERENCE_DISTANCE", AL_REFERENCE_DISTANCE },
{ "AL_ROLLOFF_FACTOR", AL_ROLLOFF_FACTOR },
{ "AL_CONE_OUTER_GAIN", AL_CONE_OUTER_GAIN },
{ "AL_MAX_DISTANCE", AL_MAX_DISTANCE },
{ "AL_SEC_OFFSET", AL_SEC_OFFSET },
{ "AL_SAMPLE_OFFSET", AL_SAMPLE_OFFSET },
{ "AL_SAMPLE_RW_OFFSETS_SOFT", AL_SAMPLE_RW_OFFSETS_SOFT },
{ "AL_BYTE_OFFSET", AL_BYTE_OFFSET },
{ "AL_BYTE_RW_OFFSETS_SOFT", AL_BYTE_RW_OFFSETS_SOFT },
{ "AL_SOURCE_TYPE", AL_SOURCE_TYPE },
{ "AL_STATIC", AL_STATIC },
{ "AL_STREAMING", AL_STREAMING },
{ "AL_UNDETERMINED", AL_UNDETERMINED },
{ "AL_METERS_PER_UNIT", AL_METERS_PER_UNIT },
// Source EFX Properties
{ "AL_DIRECT_FILTER", AL_DIRECT_FILTER },
{ "AL_AUXILIARY_SEND_FILTER", AL_AUXILIARY_SEND_FILTER },
{ "AL_AIR_ABSORPTION_FACTOR", AL_AIR_ABSORPTION_FACTOR },
{ "AL_ROOM_ROLLOFF_FACTOR", AL_ROOM_ROLLOFF_FACTOR },
{ "AL_CONE_OUTER_GAINHF", AL_CONE_OUTER_GAINHF },
{ "AL_DIRECT_FILTER_GAINHF_AUTO", AL_DIRECT_FILTER_GAINHF_AUTO },
{ "AL_AUXILIARY_SEND_FILTER_GAIN_AUTO", AL_AUXILIARY_SEND_FILTER_GAIN_AUTO },
{ "AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO", AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO},
// Source State information
{ "AL_SOURCE_STATE", AL_SOURCE_STATE },
{ "AL_INITIAL", AL_INITIAL },
{ "AL_PLAYING", AL_PLAYING },
{ "AL_PAUSED", AL_PAUSED },
{ "AL_STOPPED", AL_STOPPED },
// Queue information
{ "AL_BUFFERS_QUEUED", AL_BUFFERS_QUEUED },
{ "AL_BUFFERS_PROCESSED", AL_BUFFERS_PROCESSED },
// Buffer Formats
{ "AL_FORMAT_MONO8", AL_FORMAT_MONO8 },
{ "AL_FORMAT_MONO16", AL_FORMAT_MONO16 },
{ "AL_FORMAT_MONO_FLOAT32", AL_FORMAT_MONO_FLOAT32 },
{ "AL_FORMAT_MONO_DOUBLE_EXT", AL_FORMAT_MONO_DOUBLE_EXT },
{ "AL_FORMAT_STEREO8", AL_FORMAT_STEREO8 },
{ "AL_FORMAT_STEREO16", AL_FORMAT_STEREO16 },
{ "AL_FORMAT_STEREO_FLOAT32", AL_FORMAT_STEREO_FLOAT32 },
{ "AL_FORMAT_STEREO_DOUBLE_EXT", AL_FORMAT_STEREO_DOUBLE_EXT },
{ "AL_FORMAT_MONO_IMA4", AL_FORMAT_MONO_IMA4 },
{ "AL_FORMAT_STEREO_IMA4", AL_FORMAT_STEREO_IMA4 },
{ "AL_FORMAT_QUAD8_LOKI", AL_FORMAT_QUAD8_LOKI },
{ "AL_FORMAT_QUAD16_LOKI", AL_FORMAT_QUAD16_LOKI },
{ "AL_FORMAT_QUAD8", AL_FORMAT_QUAD8 },
{ "AL_FORMAT_QUAD16", AL_FORMAT_QUAD16 },
{ "AL_FORMAT_QUAD32", AL_FORMAT_QUAD32 },
{ "AL_FORMAT_51CHN8", AL_FORMAT_51CHN8 },
{ "AL_FORMAT_51CHN16", AL_FORMAT_51CHN16 },
{ "AL_FORMAT_51CHN32", AL_FORMAT_51CHN32 },
{ "AL_FORMAT_61CHN8", AL_FORMAT_61CHN8 },
{ "AL_FORMAT_61CHN16", AL_FORMAT_61CHN16 },
{ "AL_FORMAT_61CHN32", AL_FORMAT_61CHN32 },
{ "AL_FORMAT_71CHN8", AL_FORMAT_71CHN8 },
{ "AL_FORMAT_71CHN16", AL_FORMAT_71CHN16 },
{ "AL_FORMAT_71CHN32", AL_FORMAT_71CHN32 },
{ "AL_FORMAT_REAR8", AL_FORMAT_REAR8 },
{ "AL_FORMAT_REAR16", AL_FORMAT_REAR16 },
{ "AL_FORMAT_REAR32", AL_FORMAT_REAR32 },
{ "AL_FORMAT_MONO_MULAW", AL_FORMAT_MONO_MULAW },
{ "AL_FORMAT_MONO_MULAW_EXT", AL_FORMAT_MONO_MULAW },
{ "AL_FORMAT_STEREO_MULAW", AL_FORMAT_STEREO_MULAW },
{ "AL_FORMAT_STEREO_MULAW_EXT", AL_FORMAT_STEREO_MULAW },
{ "AL_FORMAT_QUAD_MULAW", AL_FORMAT_QUAD_MULAW },
{ "AL_FORMAT_51CHN_MULAW", AL_FORMAT_51CHN_MULAW },
{ "AL_FORMAT_61CHN_MULAW", AL_FORMAT_61CHN_MULAW },
{ "AL_FORMAT_71CHN_MULAW", AL_FORMAT_71CHN_MULAW },
{ "AL_FORMAT_REAR_MULAW", AL_FORMAT_REAR_MULAW },
// Buffer attributes
{ "AL_FREQUENCY", AL_FREQUENCY },
{ "AL_BITS", AL_BITS },
{ "AL_CHANNELS", AL_CHANNELS },
{ "AL_SIZE", AL_SIZE },
// Buffer States (not supported yet)
{ "AL_UNUSED", AL_UNUSED },
{ "AL_PENDING", AL_PENDING },
{ "AL_PROCESSED", AL_PROCESSED },
// AL Error Messages
{ "AL_NO_ERROR", AL_NO_ERROR },
{ "AL_INVALID_NAME", AL_INVALID_NAME },
{ "AL_INVALID_ENUM", AL_INVALID_ENUM },
{ "AL_INVALID_VALUE", AL_INVALID_VALUE },
{ "AL_INVALID_OPERATION", AL_INVALID_OPERATION },
{ "AL_OUT_OF_MEMORY", AL_OUT_OF_MEMORY },
// Context strings
{ "AL_VENDOR", AL_VENDOR },
{ "AL_VERSION", AL_VERSION },
{ "AL_RENDERER", AL_RENDERER },
{ "AL_EXTENSIONS", AL_EXTENSIONS },
// Global states
{ "AL_DOPPLER_FACTOR", AL_DOPPLER_FACTOR },
{ "AL_DOPPLER_VELOCITY", AL_DOPPLER_VELOCITY },
{ "AL_DISTANCE_MODEL", AL_DISTANCE_MODEL },
{ "AL_SPEED_OF_SOUND", AL_SPEED_OF_SOUND },
{ "AL_SOURCE_DISTANCE_MODEL", AL_SOURCE_DISTANCE_MODEL },
// Distance Models
{ "AL_INVERSE_DISTANCE", AL_INVERSE_DISTANCE },
{ "AL_INVERSE_DISTANCE_CLAMPED", AL_INVERSE_DISTANCE_CLAMPED },
{ "AL_LINEAR_DISTANCE", AL_LINEAR_DISTANCE },
{ "AL_LINEAR_DISTANCE_CLAMPED", AL_LINEAR_DISTANCE_CLAMPED },
{ "AL_EXPONENT_DISTANCE", AL_EXPONENT_DISTANCE },
{ "AL_EXPONENT_DISTANCE_CLAMPED", AL_EXPONENT_DISTANCE_CLAMPED },
// Filter types
{ "AL_FILTER_TYPE", AL_FILTER_TYPE },
{ "AL_FILTER_NULL", AL_FILTER_NULL },
{ "AL_FILTER_LOWPASS", AL_FILTER_LOWPASS },
#if 0
{ "AL_FILTER_HIGHPASS", AL_FILTER_HIGHPASS },
{ "AL_FILTER_BANDPASS", AL_FILTER_BANDPASS },
#endif
// Filter params
{ "AL_LOWPASS_GAIN", AL_LOWPASS_GAIN },
{ "AL_LOWPASS_GAINHF", AL_LOWPASS_GAINHF },
// Effect types
{ "AL_EFFECT_TYPE", AL_EFFECT_TYPE },
{ "AL_EFFECT_NULL", AL_EFFECT_NULL },
{ "AL_EFFECT_REVERB", AL_EFFECT_REVERB },
{ "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB },
#if 0
{ "AL_EFFECT_CHORUS", AL_EFFECT_CHORUS },
{ "AL_EFFECT_DISTORTION", AL_EFFECT_DISTORTION },
#endif
{ "AL_EFFECT_ECHO", AL_EFFECT_ECHO },
#if 0
{ "AL_EFFECT_FLANGER", AL_EFFECT_FLANGER },
{ "AL_EFFECT_FREQUENCY_SHIFTER", AL_EFFECT_FREQUENCY_SHIFTER },
{ "AL_EFFECT_VOCAL_MORPHER", AL_EFFECT_VOCAL_MORPHER },
{ "AL_EFFECT_PITCH_SHIFTER", AL_EFFECT_PITCH_SHIFTER },
#endif
{ "AL_EFFECT_RING_MODULATOR", AL_EFFECT_RING_MODULATOR },
#if 0
{ "AL_EFFECT_AUTOWAH", AL_EFFECT_AUTOWAH },
{ "AL_EFFECT_COMPRESSOR", AL_EFFECT_COMPRESSOR },
{ "AL_EFFECT_EQUALIZER", AL_EFFECT_EQUALIZER },
#endif
// Reverb params
{ "AL_REVERB_DENSITY", AL_REVERB_DENSITY },
{ "AL_REVERB_DIFFUSION", AL_REVERB_DIFFUSION },
{ "AL_REVERB_GAIN", AL_REVERB_GAIN },
{ "AL_REVERB_GAINHF", AL_REVERB_GAINHF },
{ "AL_REVERB_DECAY_TIME", AL_REVERB_DECAY_TIME },
{ "AL_REVERB_DECAY_HFRATIO", AL_REVERB_DECAY_HFRATIO },
{ "AL_REVERB_REFLECTIONS_GAIN", AL_REVERB_REFLECTIONS_GAIN },
{ "AL_REVERB_REFLECTIONS_DELAY", AL_REVERB_REFLECTIONS_DELAY },
{ "AL_REVERB_LATE_REVERB_GAIN", AL_REVERB_LATE_REVERB_GAIN },
{ "AL_REVERB_LATE_REVERB_DELAY", AL_REVERB_LATE_REVERB_DELAY },
{ "AL_REVERB_AIR_ABSORPTION_GAINHF", AL_REVERB_AIR_ABSORPTION_GAINHF },
{ "AL_REVERB_ROOM_ROLLOFF_FACTOR", AL_REVERB_ROOM_ROLLOFF_FACTOR },
{ "AL_REVERB_DECAY_HFLIMIT", AL_REVERB_DECAY_HFLIMIT },
// EAX Reverb params
{ "AL_EAXREVERB_DENSITY", AL_EAXREVERB_DENSITY },
{ "AL_EAXREVERB_DIFFUSION", AL_EAXREVERB_DIFFUSION },
{ "AL_EAXREVERB_GAIN", AL_EAXREVERB_GAIN },
{ "AL_EAXREVERB_GAINHF", AL_EAXREVERB_GAINHF },
{ "AL_EAXREVERB_GAINLF", AL_EAXREVERB_GAINLF },
{ "AL_EAXREVERB_DECAY_TIME", AL_EAXREVERB_DECAY_TIME },
{ "AL_EAXREVERB_DECAY_HFRATIO", AL_EAXREVERB_DECAY_HFRATIO },
{ "AL_EAXREVERB_DECAY_LFRATIO", AL_EAXREVERB_DECAY_LFRATIO },
{ "AL_EAXREVERB_REFLECTIONS_GAIN", AL_EAXREVERB_REFLECTIONS_GAIN },
{ "AL_EAXREVERB_REFLECTIONS_DELAY", AL_EAXREVERB_REFLECTIONS_DELAY },
{ "AL_EAXREVERB_REFLECTIONS_PAN", AL_EAXREVERB_REFLECTIONS_PAN },
{ "AL_EAXREVERB_LATE_REVERB_GAIN", AL_EAXREVERB_LATE_REVERB_GAIN },
{ "AL_EAXREVERB_LATE_REVERB_DELAY", AL_EAXREVERB_LATE_REVERB_DELAY },
{ "AL_EAXREVERB_LATE_REVERB_PAN", AL_EAXREVERB_LATE_REVERB_PAN },
{ "AL_EAXREVERB_ECHO_TIME", AL_EAXREVERB_ECHO_TIME },
{ "AL_EAXREVERB_ECHO_DEPTH", AL_EAXREVERB_ECHO_DEPTH },
{ "AL_EAXREVERB_MODULATION_TIME", AL_EAXREVERB_MODULATION_TIME },
{ "AL_EAXREVERB_MODULATION_DEPTH", AL_EAXREVERB_MODULATION_DEPTH },
{ "AL_EAXREVERB_AIR_ABSORPTION_GAINHF", AL_EAXREVERB_AIR_ABSORPTION_GAINHF },
{ "AL_EAXREVERB_HFREFERENCE", AL_EAXREVERB_HFREFERENCE },
{ "AL_EAXREVERB_LFREFERENCE", AL_EAXREVERB_LFREFERENCE },
{ "AL_EAXREVERB_ROOM_ROLLOFF_FACTOR", AL_EAXREVERB_ROOM_ROLLOFF_FACTOR },
{ "AL_EAXREVERB_DECAY_HFLIMIT", AL_EAXREVERB_DECAY_HFLIMIT },
// Echo params
{ "AL_ECHO_DELAY", AL_ECHO_DELAY },
{ "AL_ECHO_LRDELAY", AL_ECHO_LRDELAY },
{ "AL_ECHO_DAMPING", AL_ECHO_DAMPING },
{ "AL_ECHO_FEEDBACK", AL_ECHO_FEEDBACK },
{ "AL_ECHO_SPREAD", AL_ECHO_SPREAD },
// Ring Modulator params
{ "AL_RING_MODULATOR_FREQUENCY", AL_RING_MODULATOR_FREQUENCY },
{ "AL_RING_MODULATOR_HIGHPASS_CUTOFF", AL_RING_MODULATOR_HIGHPASS_CUTOFF },
{ "AL_RING_MODULATOR_WAVEFORM", AL_RING_MODULATOR_WAVEFORM },
// Default
{ NULL, (ALenum)0 }
};
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
{
ALboolean bIsSupported = AL_FALSE;
ALCcontext *pContext;
const char *ptr;
size_t len;
pContext = GetContextSuspended();
if(!pContext) return AL_FALSE;
if(!extName)
{
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
return AL_FALSE;
}
len = strlen(extName);
ptr = pContext->ExtensionList;
while(ptr && *ptr)
{
if(strncasecmp(ptr, extName, len) == 0 &&
(ptr[len] == '\0' || isspace(ptr[len])))
{
bIsSupported = AL_TRUE;
break;
}
if((ptr=strchr(ptr, ' ')) != NULL)
{
do {
++ptr;
} while(isspace(*ptr));
}
}
ProcessContext(pContext);
return bIsSupported;
}
AL_API ALvoid* AL_APIENTRY alGetProcAddress(const ALchar *funcName)
{
if(!funcName)
return NULL;
return alcGetProcAddress(NULL, funcName);
}
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *enumName)
{
ALsizei i = 0;
while(enumeration[i].enumName &&
strcmp(enumeration[i].enumName, enumName) != 0)
i++;
return enumeration[i].value;
}

View File

@ -0,0 +1,432 @@
/**
* 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 "AL/al.h"
#include "AL/alc.h"
#include "alMain.h"
#include "alFilter.h"
#include "alThunk.h"
#include "alError.h"
static void InitFilterParams(ALfilter *filter, ALenum type);
#define LookupFilter(m, k) ((ALfilter*)LookupUIntMapKey(&(m), (k)))
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
{
ALCcontext *Context;
ALsizei i=0;
Context = GetContextSuspended();
if(!Context) return;
if(n < 0 || IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
alSetError(Context, AL_INVALID_VALUE);
else
{
ALCdevice *device = Context->Device;
ALenum err;
while(i < n)
{
ALfilter *filter = calloc(1, sizeof(ALfilter));
if(!filter)
{
alSetError(Context, AL_OUT_OF_MEMORY);
alDeleteFilters(i, filters);
break;
}
filter->filter = ALTHUNK_ADDENTRY(filter);
err = InsertUIntMapEntry(&device->FilterMap, filter->filter, filter);
if(err != AL_NO_ERROR)
{
ALTHUNK_REMOVEENTRY(filter->filter);
memset(filter, 0, sizeof(ALfilter));
free(filter);
alSetError(Context, err);
alDeleteFilters(i, filters);
break;
}
filters[i++] = filter->filter;
InitFilterParams(filter, AL_FILTER_NULL);
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters)
{
ALCcontext *Context;
ALCdevice *device;
ALfilter *ALFilter;
ALboolean Failed;
ALsizei i;
Context = GetContextSuspended();
if(!Context) return;
Failed = AL_TRUE;
device = Context->Device;
if(n < 0)
alSetError(Context, AL_INVALID_VALUE);
else
{
Failed = AL_FALSE;
// Check that all filters are valid
for(i = 0;i < n;i++)
{
if(!filters[i])
continue;
if(LookupFilter(device->FilterMap, filters[i]) == NULL)
{
alSetError(Context, AL_INVALID_NAME);
Failed = AL_TRUE;
break;
}
}
}
if(!Failed)
{
// All filters are valid
for(i = 0;i < n;i++)
{
// Recheck that the filter is valid, because there could be duplicated names
if((ALFilter=LookupFilter(device->FilterMap, filters[i])) == NULL)
continue;
RemoveUIntMapKey(&device->FilterMap, ALFilter->filter);
ALTHUNK_REMOVEENTRY(ALFilter->filter);
memset(ALFilter, 0, sizeof(ALfilter));
free(ALFilter);
}
}
ProcessContext(Context);
}
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
{
ALCcontext *Context;
ALboolean result;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
result = ((!filter || LookupFilter(Context->Device->FilterMap, filter)) ?
AL_TRUE : AL_FALSE);
ProcessContext(Context);
return result;
}
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
{
ALCcontext *Context;
ALCdevice *Device;
ALfilter *ALFilter;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((ALFilter=LookupFilter(Device->FilterMap, filter)) != NULL)
{
switch(param)
{
case AL_FILTER_TYPE:
if(iValue == AL_FILTER_NULL ||
iValue == AL_FILTER_LOWPASS)
InitFilterParams(ALFilter, iValue);
else
alSetError(Context, AL_INVALID_VALUE);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues)
{
ALCcontext *Context;
ALCdevice *Device;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if(LookupFilter(Device->FilterMap, filter) != NULL)
{
switch(param)
{
case AL_FILTER_TYPE:
alFilteri(filter, param, piValues[0]);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flArg)
{
ALCcontext *Context;
ALCdevice *Device;
ALfilter *ALFilter;
ALfp flValue = float2ALfp(flArg);
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((ALFilter=LookupFilter(Device->FilterMap, filter)) != NULL)
{
switch(ALFilter->type)
{
case AL_FILTER_LOWPASS:
switch(param)
{
case AL_LOWPASS_GAIN:
if(flValue >= int2ALfp(0) && flValue <= int2ALfp(1))
ALFilter->Gain = flValue;
else
alSetError(Context, AL_INVALID_VALUE);
break;
case AL_LOWPASS_GAINHF:
if(flValue >= int2ALfp(0) && flValue <= int2ALfp(1))
ALFilter->GainHF = flValue;
else
alSetError(Context, AL_INVALID_VALUE);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
{
ALCcontext *Context;
ALCdevice *Device;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if(LookupFilter(Device->FilterMap, filter) != NULL)
{
switch(param)
{
default:
alFilterf(filter, param, pflValues[0]);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
{
ALCcontext *Context;
ALCdevice *Device;
ALfilter *ALFilter;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((ALFilter=LookupFilter(Device->FilterMap, filter)) != NULL)
{
switch(param)
{
case AL_FILTER_TYPE:
*piValue = ALFilter->type;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
{
ALCcontext *Context;
ALCdevice *Device;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if(LookupFilter(Device->FilterMap, filter) != NULL)
{
switch(param)
{
case AL_FILTER_TYPE:
alGetFilteri(filter, param, piValues);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
{
ALCcontext *Context;
ALCdevice *Device;
ALfilter *ALFilter;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if((ALFilter=LookupFilter(Device->FilterMap, filter)) != NULL)
{
switch(ALFilter->type)
{
case AL_FILTER_LOWPASS:
switch(param)
{
case AL_LOWPASS_GAIN:
*pflValue = ALfp2float(ALFilter->Gain);
break;
case AL_LOWPASS_GAINHF:
*pflValue = ALfp2float(ALFilter->GainHF);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
{
ALCcontext *Context;
ALCdevice *Device;
Context = GetContextSuspended();
if(!Context) return;
Device = Context->Device;
if(LookupFilter(Device->FilterMap, filter) != NULL)
{
switch(param)
{
default:
alGetFilterf(filter, param, pflValues);
break;
}
}
else
alSetError(Context, AL_INVALID_NAME);
ProcessContext(Context);
}
ALvoid ReleaseALFilters(ALCdevice *device)
{
ALsizei i;
for(i = 0;i < device->FilterMap.size;i++)
{
ALfilter *temp = device->FilterMap.array[i].value;
device->FilterMap.array[i].value = NULL;
// Release filter structure
ALTHUNK_REMOVEENTRY(temp->filter);
memset(temp, 0, sizeof(ALfilter));
free(temp);
}
}
static void InitFilterParams(ALfilter *filter, ALenum type)
{
filter->type = type;
filter->Gain = int2ALfp(1);
filter->GainHF = int2ALfp(1);
}

View File

@ -0,0 +1,489 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 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 "alMain.h"
#include "AL/alc.h"
#include "alError.h"
#include "alListener.h"
#include "alSource.h"
AL_API ALvoid AL_APIENTRY alListenerf(ALenum eParam, ALfloat flArg)
{
ALCcontext *pContext;
ALboolean updateAll = AL_FALSE;
ALfp flValue = float2ALfp(flArg);
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
case AL_GAIN:
if(flValue >= int2ALfp(0))
{
pContext->Listener.Gain = flValue;
updateAll = AL_TRUE;
}
else
alSetError(pContext, AL_INVALID_VALUE);
break;
case AL_METERS_PER_UNIT:
if(flValue > int2ALfp(0))
{
pContext->Listener.MetersPerUnit = flValue;
updateAll = AL_TRUE;
}
else
alSetError(pContext, AL_INVALID_VALUE);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
// Force updating the sources for these parameters, since even head-
// relative sources are affected
if(updateAll)
{
ALsizei pos;
for(pos = 0;pos < pContext->SourceMap.size;pos++)
{
ALsource *source = pContext->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alListener3f(ALenum eParam, ALfloat flArg1, ALfloat flArg2, ALfloat flArg3)
{
ALCcontext *pContext;
ALboolean updateWorld = AL_FALSE;
ALfp flValue1 = float2ALfp(flArg1);
ALfp flValue2 = float2ALfp(flArg2);
ALfp flValue3 = float2ALfp(flArg3);
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
case AL_POSITION:
pContext->Listener.Position[0] = flValue1;
pContext->Listener.Position[1] = flValue2;
pContext->Listener.Position[2] = flValue3;
updateWorld = AL_TRUE;
break;
case AL_VELOCITY:
pContext->Listener.Velocity[0] = flValue1;
pContext->Listener.Velocity[1] = flValue2;
pContext->Listener.Velocity[2] = flValue3;
updateWorld = AL_TRUE;
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
if(updateWorld)
{
ALsizei pos;
for(pos = 0;pos < pContext->SourceMap.size;pos++)
{
ALsource *source = pContext->SourceMap.array[pos].value;
if(!source->bHeadRelative)
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
{
ALCcontext *pContext;
ALboolean updateWorld = AL_FALSE;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValues)
{
switch(eParam)
{
case AL_GAIN:
case AL_METERS_PER_UNIT:
alListenerf(eParam, pflValues[0]);
break;
case AL_POSITION:
case AL_VELOCITY:
alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]);
break;
case AL_ORIENTATION:
// AT then UP
pContext->Listener.Forward[0] = float2ALfp(pflValues[0]);
pContext->Listener.Forward[1] = float2ALfp(pflValues[1]);
pContext->Listener.Forward[2] = float2ALfp(pflValues[2]);
pContext->Listener.Up[0] = float2ALfp(pflValues[3]);
pContext->Listener.Up[1] = float2ALfp(pflValues[4]);
pContext->Listener.Up[2] = float2ALfp(pflValues[5]);
updateWorld = AL_TRUE;
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
if(updateWorld)
{
ALsizei pos;
for(pos = 0;pos < pContext->SourceMap.size;pos++)
{
ALsource *source = pContext->SourceMap.array[pos].value;
if(!source->bHeadRelative)
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alListeneri(ALenum eParam, ALint lValue)
{
ALCcontext *pContext;
(void)lValue;
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
AL_API void AL_APIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
switch(eParam)
{
case AL_POSITION:
case AL_VELOCITY:
alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
}
AL_API void AL_APIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
{
ALCcontext *pContext;
ALfloat flValues[6];
pContext = GetContextSuspended();
if(!pContext) return;
if(plValues)
{
switch(eParam)
{
case AL_POSITION:
case AL_VELOCITY:
flValues[0] = (ALfloat)plValues[0];
flValues[1] = (ALfloat)plValues[1];
flValues[2] = (ALfloat)plValues[2];
alListenerfv(eParam, flValues);
break;
case AL_ORIENTATION:
flValues[0] = (ALfloat)plValues[0];
flValues[1] = (ALfloat)plValues[1];
flValues[2] = (ALfloat)plValues[2];
flValues[3] = (ALfloat)plValues[3];
flValues[4] = (ALfloat)plValues[4];
flValues[5] = (ALfloat)plValues[5];
alListenerfv(eParam, flValues);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValue)
{
switch(eParam)
{
case AL_GAIN:
*pflValue = ALfp2float(pContext->Listener.Gain);
break;
case AL_METERS_PER_UNIT:
*pflValue = ALfp2float(pContext->Listener.MetersPerUnit);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValue1 && pflValue2 && pflValue3)
{
switch(eParam)
{
case AL_POSITION:
*pflValue1 = ALfp2float(pContext->Listener.Position[0]);
*pflValue2 = ALfp2float(pContext->Listener.Position[1]);
*pflValue3 = ALfp2float(pContext->Listener.Position[2]);
break;
case AL_VELOCITY:
*pflValue1 = ALfp2float(pContext->Listener.Velocity[0]);
*pflValue2 = ALfp2float(pContext->Listener.Velocity[1]);
*pflValue3 = ALfp2float(pContext->Listener.Velocity[2]);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(pflValues)
{
switch(eParam)
{
case AL_GAIN:
pflValues[0] = ALfp2float(pContext->Listener.Gain);
break;
case AL_METERS_PER_UNIT:
pflValues[0] = ALfp2float(pContext->Listener.MetersPerUnit);
break;
case AL_POSITION:
pflValues[0] = ALfp2float(pContext->Listener.Position[0]);
pflValues[1] = ALfp2float(pContext->Listener.Position[1]);
pflValues[2] = ALfp2float(pContext->Listener.Position[2]);
break;
case AL_VELOCITY:
pflValues[0] = ALfp2float(pContext->Listener.Velocity[0]);
pflValues[1] = ALfp2float(pContext->Listener.Velocity[1]);
pflValues[2] = ALfp2float(pContext->Listener.Velocity[2]);
break;
case AL_ORIENTATION:
// AT then UP
pflValues[0] = ALfp2float(pContext->Listener.Forward[0]);
pflValues[1] = ALfp2float(pContext->Listener.Forward[1]);
pflValues[2] = ALfp2float(pContext->Listener.Forward[2]);
pflValues[3] = ALfp2float(pContext->Listener.Up[0]);
pflValues[4] = ALfp2float(pContext->Listener.Up[1]);
pflValues[5] = ALfp2float(pContext->Listener.Up[2]);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValue)
{
switch(eParam)
{
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API void AL_APIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValue1 && plValue2 && plValue3)
{
switch (eParam)
{
case AL_POSITION:
*plValue1 = (ALint)ALfp2int(pContext->Listener.Position[0]);
*plValue2 = (ALint)ALfp2int(pContext->Listener.Position[1]);
*plValue3 = (ALint)ALfp2int(pContext->Listener.Position[2]);
break;
case AL_VELOCITY:
*plValue1 = (ALint)ALfp2int(pContext->Listener.Velocity[0]);
*plValue2 = (ALint)ALfp2int(pContext->Listener.Velocity[1]);
*plValue3 = (ALint)ALfp2int(pContext->Listener.Velocity[2]);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}
AL_API void AL_APIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
{
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return;
if(plValues)
{
switch(eParam)
{
case AL_POSITION:
plValues[0] = (ALint)ALfp2int(pContext->Listener.Position[0]);
plValues[1] = (ALint)ALfp2int(pContext->Listener.Position[1]);
plValues[2] = (ALint)ALfp2int(pContext->Listener.Position[2]);
break;
case AL_VELOCITY:
plValues[0] = (ALint)ALfp2int(pContext->Listener.Velocity[0]);
plValues[1] = (ALint)ALfp2int(pContext->Listener.Velocity[1]);
plValues[2] = (ALint)ALfp2int(pContext->Listener.Velocity[2]);
break;
case AL_ORIENTATION:
// AT then UP
plValues[0] = (ALint)ALfp2int(pContext->Listener.Forward[0]);
plValues[1] = (ALint)ALfp2int(pContext->Listener.Forward[1]);
plValues[2] = (ALint)ALfp2int(pContext->Listener.Forward[2]);
plValues[3] = (ALint)ALfp2int(pContext->Listener.Up[0]);
plValues[4] = (ALint)ALfp2int(pContext->Listener.Up[1]);
plValues[5] = (ALint)ALfp2int(pContext->Listener.Up[2]);
break;
default:
alSetError(pContext, AL_INVALID_ENUM);
break;
}
}
else
alSetError(pContext, AL_INVALID_VALUE);
ProcessContext(pContext);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,661 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 1999-2000 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 "AL/alc.h"
#include "AL/alext.h"
#include "alError.h"
#include "alSource.h"
#include "alState.h"
#include "alDatabuffer.h"
static const ALchar alVendor[] = "OpenAL Community";
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
static const ALchar alRenderer[] = "OpenAL Soft";
// Error Messages
static const ALchar alNoError[] = "No Error";
static const ALchar alErrInvalidName[] = "Invalid Name";
static const ALchar alErrInvalidEnum[] = "Invalid Enum";
static const ALchar alErrInvalidValue[] = "Invalid Value";
static const ALchar alErrInvalidOp[] = "Invalid Operation";
static const ALchar alErrOutOfMemory[] = "Out of Memory";
AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
switch(capability)
{
case AL_SOURCE_DISTANCE_MODEL:
Context->SourceDistanceModel = AL_TRUE;
updateSources = AL_TRUE;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
switch(capability)
{
case AL_SOURCE_DISTANCE_MODEL:
Context->SourceDistanceModel = AL_FALSE;
updateSources = AL_TRUE;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(Context);
}
AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
{
ALCcontext *Context;
ALboolean value=AL_FALSE;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
switch(capability)
{
case AL_SOURCE_DISTANCE_MODEL:
value = Context->SourceDistanceModel;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
{
ALCcontext *Context;
ALboolean value=AL_FALSE;
Context = GetContextSuspended();
if(!Context) return AL_FALSE;
switch(pname)
{
case AL_DOPPLER_FACTOR:
if(Context->DopplerFactor != int2ALfp(0))
value = AL_TRUE;
break;
case AL_DOPPLER_VELOCITY:
if(Context->DopplerVelocity != int2ALfp(0))
value = AL_TRUE;
break;
case AL_DISTANCE_MODEL:
if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
value = AL_TRUE;
break;
case AL_SPEED_OF_SOUND:
if(Context->flSpeedOfSound != int2ALfp(0))
value = AL_TRUE;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
{
ALCcontext *Context;
ALdouble value = 0.0;
Context = GetContextSuspended();
if(!Context) return 0.0;
switch(pname)
{
case AL_DOPPLER_FACTOR:
value = (double)ALfp2float(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
value = (double)ALfp2float(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
value = (double)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = (double)ALfp2float(Context->flSpeedOfSound);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
{
ALCcontext *Context;
ALfloat value = 0.0f;
Context = GetContextSuspended();
if(!Context) return 0.0f;
switch(pname)
{
case AL_DOPPLER_FACTOR:
value = ALfp2float(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
value = ALfp2float(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
value = (float)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = ALfp2float(Context->flSpeedOfSound);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
{
ALCcontext *Context;
ALint value = 0;
Context = GetContextSuspended();
if(!Context) return 0;
switch(pname)
{
case AL_DOPPLER_FACTOR:
value = (ALint)ALfp2int(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
value = (ALint)ALfp2int(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
value = (ALint)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
value = (ALint)ALfp2int(Context->flSpeedOfSound);
break;
case AL_SAMPLE_SOURCE_EXT:
if(Context->SampleSource)
value = (ALint)Context->SampleSource->databuffer;
else
value = 0;
break;
case AL_SAMPLE_SINK_EXT:
if(Context->SampleSink)
value = (ALint)Context->SampleSink->databuffer;
else
value = 0;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
ProcessContext(Context);
return value;
}
AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
switch(pname)
{
case AL_DOPPLER_FACTOR:
*data = (ALboolean)((Context->DopplerFactor != int2ALfp(0)) ? AL_TRUE : AL_FALSE);
break;
case AL_DOPPLER_VELOCITY:
*data = (ALboolean)((Context->DopplerVelocity != int2ALfp(0)) ? AL_TRUE : AL_FALSE);
break;
case AL_DISTANCE_MODEL:
*data = (ALboolean)((Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED) ? AL_TRUE : AL_FALSE);
break;
case AL_SPEED_OF_SOUND:
*data = (ALboolean)((Context->flSpeedOfSound != int2ALfp(0)) ? AL_TRUE : AL_FALSE);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
{
// data is a NULL pointer
alSetError(Context, AL_INVALID_VALUE);
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
switch(pname)
{
case AL_DOPPLER_FACTOR:
*data = (double)ALfp2float(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
*data = (double)ALfp2float(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
*data = (double)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = (double)ALfp2float(Context->flSpeedOfSound);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
{
// data is a NULL pointer
alSetError(Context, AL_INVALID_VALUE);
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
switch(pname)
{
case AL_DOPPLER_FACTOR:
*data = ALfp2float(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
*data = ALfp2float(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
*data = (float)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = ALfp2float(Context->flSpeedOfSound);
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
{
// data is a NULL pointer
alSetError(Context, AL_INVALID_VALUE);
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data)
{
ALCcontext *Context;
Context = GetContextSuspended();
if(!Context) return;
if(data)
{
switch(pname)
{
case AL_DOPPLER_FACTOR:
*data = (ALint)ALfp2int(Context->DopplerFactor);
break;
case AL_DOPPLER_VELOCITY:
*data = (ALint)ALfp2int(Context->DopplerVelocity);
break;
case AL_DISTANCE_MODEL:
*data = (ALint)Context->DistanceModel;
break;
case AL_SPEED_OF_SOUND:
*data = (ALint)ALfp2int(Context->flSpeedOfSound);
break;
case AL_SAMPLE_SOURCE_EXT:
if(Context->SampleSource)
*data = (ALint)Context->SampleSource->databuffer;
else
*data = 0;
break;
case AL_SAMPLE_SINK_EXT:
if(Context->SampleSink)
*data = (ALint)Context->SampleSink->databuffer;
else
*data = 0;
break;
default:
alSetError(Context, AL_INVALID_ENUM);
break;
}
}
else
{
// data is a NULL pointer
alSetError(Context, AL_INVALID_VALUE);
}
ProcessContext(Context);
}
AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
{
const ALchar *value;
ALCcontext *pContext;
pContext = GetContextSuspended();
if(!pContext) return NULL;
switch(pname)
{
case AL_VENDOR:
value=alVendor;
break;
case AL_VERSION:
value=alVersion;
break;
case AL_RENDERER:
value=alRenderer;
break;
case AL_EXTENSIONS:
value=pContext->ExtensionList;//alExtensions;
break;
case AL_NO_ERROR:
value=alNoError;
break;
case AL_INVALID_NAME:
value=alErrInvalidName;
break;
case AL_INVALID_ENUM:
value=alErrInvalidEnum;
break;
case AL_INVALID_VALUE:
value=alErrInvalidValue;
break;
case AL_INVALID_OPERATION:
value=alErrInvalidOp;
break;
case AL_OUT_OF_MEMORY:
value=alErrOutOfMemory;
break;
default:
value=NULL;
alSetError(pContext, AL_INVALID_ENUM);
break;
}
ProcessContext(pContext);
return value;
}
AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
if(value >= 0.0f)
{
Context->DopplerFactor = float2ALfp(value);
updateSources = AL_TRUE;
}
else
alSetError(Context, AL_INVALID_VALUE);
// Force updating the sources for these parameters, since even head-
// relative sources are affected
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
if(value > 0.0f)
{
Context->DopplerVelocity=float2ALfp(value);
updateSources = AL_TRUE;
}
else
alSetError(Context, AL_INVALID_VALUE);
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(Context);
}
AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat flSpeedOfSound)
{
ALCcontext *pContext;
ALboolean updateSources = AL_FALSE;
pContext = GetContextSuspended();
if(!pContext) return;
if(flSpeedOfSound > 0.0f)
{
pContext->flSpeedOfSound = float2ALfp(flSpeedOfSound);
updateSources = AL_TRUE;
}
else
alSetError(pContext, AL_INVALID_VALUE);
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < pContext->SourceMap.size;pos++)
{
ALsource *source = pContext->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(pContext);
}
AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
{
ALCcontext *Context;
ALboolean updateSources = AL_FALSE;
Context = GetContextSuspended();
if(!Context) return;
switch(value)
{
case AL_NONE:
case AL_INVERSE_DISTANCE:
case AL_INVERSE_DISTANCE_CLAMPED:
case AL_LINEAR_DISTANCE:
case AL_LINEAR_DISTANCE_CLAMPED:
case AL_EXPONENT_DISTANCE:
case AL_EXPONENT_DISTANCE_CLAMPED:
Context->DistanceModel = value;
updateSources = !Context->SourceDistanceModel;
break;
default:
alSetError(Context, AL_INVALID_VALUE);
break;
}
if(updateSources)
{
ALsizei pos;
for(pos = 0;pos < Context->SourceMap.size;pos++)
{
ALsource *source = Context->SourceMap.array[pos].value;
source->NeedsUpdate = AL_TRUE;
}
}
ProcessContext(Context);
}

View File

@ -0,0 +1,111 @@
/**
* 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"
typedef struct {
ALvoid *ptr;
ALboolean InUse;
} ThunkEntry;
static ThunkEntry *g_ThunkArray;
static ALuint g_ThunkArraySize;
static CRITICAL_SECTION g_ThunkLock;
void alThunkInit(void)
{
InitializeCriticalSection(&g_ThunkLock);
g_ThunkArraySize = 1;
g_ThunkArray = calloc(1, g_ThunkArraySize * sizeof(ThunkEntry));
}
void alThunkExit(void)
{
free(g_ThunkArray);
g_ThunkArray = NULL;
g_ThunkArraySize = 0;
DeleteCriticalSection(&g_ThunkLock);
}
ALuint alThunkAddEntry(ALvoid *ptr)
{
ALuint index;
EnterCriticalSection(&g_ThunkLock);
for(index = 0;index < g_ThunkArraySize;index++)
{
if(g_ThunkArray[index].InUse == AL_FALSE)
break;
}
if(index == g_ThunkArraySize)
{
ThunkEntry *NewList;
NewList = realloc(g_ThunkArray, g_ThunkArraySize*2 * sizeof(ThunkEntry));
if(!NewList)
{
LeaveCriticalSection(&g_ThunkLock);
AL_PRINT("Realloc failed to increase to %u enties!\n", g_ThunkArraySize*2);
return 0;
}
memset(&NewList[g_ThunkArraySize], 0, g_ThunkArraySize*sizeof(ThunkEntry));
g_ThunkArraySize *= 2;
g_ThunkArray = NewList;
}
g_ThunkArray[index].ptr = ptr;
g_ThunkArray[index].InUse = AL_TRUE;
LeaveCriticalSection(&g_ThunkLock);
return index+1;
}
void alThunkRemoveEntry(ALuint index)
{
EnterCriticalSection(&g_ThunkLock);
if(index > 0 && index <= g_ThunkArraySize)
g_ThunkArray[index-1].InUse = AL_FALSE;
LeaveCriticalSection(&g_ThunkLock);
}
ALvoid *alThunkLookupEntry(ALuint index)
{
ALvoid *ptr = NULL;
EnterCriticalSection(&g_ThunkLock);
if(index > 0 && index <= g_ThunkArraySize)
ptr = g_ThunkArray[index-1].ptr;
LeaveCriticalSection(&g_ThunkLock);
return ptr;
}

724
jni/OpenAL/al.h Normal file
View File

@ -0,0 +1,724 @@
#ifndef AL_AL_H
#define AL_AL_H
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(AL_LIBTYPE_STATIC)
#define AL_API
#elif defined(_WIN32) && !defined(_XBOX)
#if defined(AL_BUILD_LIBRARY)
#define AL_API __declspec(dllexport)
#else
#define AL_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define AL_API __attribute__((visibility("protected")))
#else
#define AL_API extern
#endif
#endif
#if defined(_WIN32)
#define AL_APIENTRY __cdecl
#else
#define AL_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The OPENAL, ALAPI, ALAPIENTRY, AL_INVALID, AL_ILLEGAL_ENUM, and
* AL_ILLEGAL_COMMAND macros are deprecated, but are included for
* applications porting code from AL 1.0
*/
#define OPENAL
#define ALAPI AL_API
#define ALAPIENTRY AL_APIENTRY
#define AL_INVALID (-1)
#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
#define AL_VERSION_1_0
#define AL_VERSION_1_1
/** 8-bit boolean */
typedef char ALboolean;
/** character */
typedef char ALchar;
/** signed 8-bit 2's complement integer */
typedef signed char ALbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALubyte;
/** signed 16-bit 2's complement integer */
typedef short ALshort;
/** unsigned 16-bit integer */
typedef unsigned short ALushort;
/** signed 32-bit 2's complement integer */
typedef int ALint;
/** unsigned 32-bit integer */
typedef unsigned int ALuint;
/** non-negative 32-bit binary integer size */
typedef int ALsizei;
/** enumerated 32-bit value */
typedef int ALenum;
/** 32-bit IEEE754 floating-point */
typedef float ALfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALdouble;
/** void type (for opaque pointers only) */
typedef void ALvoid;
/* Enumerant values begin at column 50. No tabs. */
/* "no distance model" or "no buffer" */
#define AL_NONE 0
/* Boolean False. */
#define AL_FALSE 0
/** Boolean True. */
#define AL_TRUE 1
/** Indicate Source has relative coordinates. */
#define AL_SOURCE_RELATIVE 0x202
/**
* Directional source, inner cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_INNER_ANGLE 0x1001
/**
* Directional source, outer cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_OUTER_ANGLE 0x1002
/**
* Specify the pitch to be applied at source.
* Range: [0.5-2.0]
* Default: 1.0
*/
#define AL_PITCH 0x1003
/**
* Specify the current location in three dimensional space.
* OpenAL, like OpenGL, uses a right handed coordinate system,
* where in a frontal default view X (thumb) points right,
* Y points up (index finger), and Z points towards the
* viewer/camera (middle finger).
* To switch from a left handed coordinate system, flip the
* sign on the Z coordinate.
* Listener position is always in the world coordinate system.
*/
#define AL_POSITION 0x1004
/** Specify the current direction. */
#define AL_DIRECTION 0x1005
/** Specify the current velocity in three dimensional space. */
#define AL_VELOCITY 0x1006
/**
* Indicate whether source is looping.
* Type: ALboolean?
* Range: [AL_TRUE, AL_FALSE]
* Default: FALSE.
*/
#define AL_LOOPING 0x1007
/**
* Indicate the buffer to provide sound samples.
* Type: ALuint.
* Range: any valid Buffer id.
*/
#define AL_BUFFER 0x1009
/**
* Indicate the gain (volume amplification) applied.
* Type: ALfloat.
* Range: ]0.0- ]
* A value of 1.0 means un-attenuated/unchanged.
* Each division by 2 equals an attenuation of -6dB.
* Each multiplicaton with 2 equals an amplification of +6dB.
* A value of 0.0 is meaningless with respect to a logarithmic
* scale; it is interpreted as zero volume - the channel
* is effectively disabled.
*/
#define AL_GAIN 0x100A
/*
* Indicate minimum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MIN_GAIN 0x100D
/**
* Indicate maximum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MAX_GAIN 0x100E
/**
* Indicate listener orientation.
*
* at/up
*/
#define AL_ORIENTATION 0x100F
/**
* Source state information.
*/
#define AL_SOURCE_STATE 0x1010
#define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013
#define AL_STOPPED 0x1014
/**
* Buffer Queue params
*/
#define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016
/**
* Source buffer position information
*/
#define AL_SEC_OFFSET 0x1024
#define AL_SAMPLE_OFFSET 0x1025
#define AL_BYTE_OFFSET 0x1026
/*
* Source type (Static, Streaming or undetermined)
* Source is Static if a Buffer has been attached using AL_BUFFER
* Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
* Source is undetermined when it has the NULL buffer attached
*/
#define AL_SOURCE_TYPE 0x1027
#define AL_STATIC 0x1028
#define AL_STREAMING 0x1029
#define AL_UNDETERMINED 0x1030
/** Sound samples: format specifier. */
#define AL_FORMAT_MONO8 0x1100
#define AL_FORMAT_MONO16 0x1101
#define AL_FORMAT_STEREO8 0x1102
#define AL_FORMAT_STEREO16 0x1103
/**
* source specific reference distance
* Type: ALfloat
* Range: 0.0 - +inf
*
* At 0.0, no distance attenuation occurs. Default is
* 1.0.
*/
#define AL_REFERENCE_DISTANCE 0x1020
/**
* source specific rolloff factor
* Type: ALfloat
* Range: 0.0 - +inf
*
*/
#define AL_ROLLOFF_FACTOR 0x1021
/**
* Directional source, outer cone gain.
*
* Default: 0.0
* Range: [0.0 - 1.0]
* Logarithmic
*/
#define AL_CONE_OUTER_GAIN 0x1022
/**
* Indicate distance above which sources are not
* attenuated using the inverse clamped distance model.
*
* Default: +inf
* Type: ALfloat
* Range: 0.0 - +inf
*/
#define AL_MAX_DISTANCE 0x1023
/**
* Sound samples: frequency, in units of Hertz [Hz].
* This is the number of samples per second. Half of the
* sample frequency marks the maximum significant
* frequency component.
*/
#define AL_FREQUENCY 0x2001
#define AL_BITS 0x2002
#define AL_CHANNELS 0x2003
#define AL_SIZE 0x2004
/**
* Buffer state.
*
* Not supported for public use (yet).
*/
#define AL_UNUSED 0x2010
#define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012
/** Errors: No Error. */
#define AL_NO_ERROR AL_FALSE
/**
* Invalid Name paramater passed to AL call.
*/
#define AL_INVALID_NAME 0xA001
/**
* Invalid parameter passed to AL call.
*/
#define AL_INVALID_ENUM 0xA002
/**
* Invalid enum parameter value.
*/
#define AL_INVALID_VALUE 0xA003
/**
* Illegal call.
*/
#define AL_INVALID_OPERATION 0xA004
/**
* No mojo.
*/
#define AL_OUT_OF_MEMORY 0xA005
/** Context strings: Vendor Name. */
#define AL_VENDOR 0xB001
#define AL_VERSION 0xB002
#define AL_RENDERER 0xB003
#define AL_EXTENSIONS 0xB004
/** Global tweakage. */
/**
* Doppler scale. Default 1.0
*/
#define AL_DOPPLER_FACTOR 0xC000
/**
* Tweaks speed of propagation.
*/
#define AL_DOPPLER_VELOCITY 0xC001
/**
* Speed of Sound in units per second
*/
#define AL_SPEED_OF_SOUND 0xC003
/**
* Distance models
*
* used in conjunction with DistanceModel
*
* implicit: NONE, which disances distance attenuation.
*/
#define AL_DISTANCE_MODEL 0xD000
#define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
#define AL_LINEAR_DISTANCE 0xD003
#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
#define AL_EXPONENT_DISTANCE 0xD005
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
/*
* Renderer State management
*/
AL_API void AL_APIENTRY alEnable( ALenum capability );
AL_API void AL_APIENTRY alDisable( ALenum capability );
AL_API ALboolean AL_APIENTRY alIsEnabled( ALenum capability );
/*
* State retrieval
*/
AL_API const ALchar* AL_APIENTRY alGetString( ALenum param );
AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data );
AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data );
AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data );
AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data );
AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param );
AL_API ALint AL_APIENTRY alGetInteger( ALenum param );
AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param );
AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param );
/*
* Error support.
* Obtain the most recent error generated in the AL state machine.
*/
AL_API ALenum AL_APIENTRY alGetError( void );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname );
AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname );
AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename );
/*
* LISTENER
* Listener represents the location and orientation of the
* 'user' in 3D-space.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors)
*/
/*
* Set Listener parameters
*/
AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value );
AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value );
AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values );
/*
* Get Listener parameters
*/
AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values );
/**
* SOURCE
* Sources represent individual sound objects in 3D-space.
* Sources take the PCM data provided in the specified Buffer,
* apply Source-specific modifications, and then
* submit them to be mixed according to spatial arrangement etc.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Min Gain AL_MIN_GAIN ALfloat
* Max Gain AL_MAX_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Direction AL_DIRECTION ALfloat[3]
* Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE)
* Reference Distance AL_REFERENCE_DISTANCE ALfloat
* Max Distance AL_MAX_DISTANCE ALfloat
* RollOff Factor AL_ROLLOFF_FACTOR ALfloat
* Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat
* Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat
* Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat
* Pitch AL_PITCH ALfloat
* Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE)
* MS Offset AL_MSEC_OFFSET ALint or ALfloat
* Byte Offset AL_BYTE_OFFSET ALint or ALfloat
* Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat
* Attached Buffer AL_BUFFER ALint
* State (Query only) AL_SOURCE_STATE ALint
* Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint
* Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint
*/
/* Create Source objects */
AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources );
/* Delete Source objects */
AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources );
/* Verify a handle is a valid Source */
AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid );
/*
* Set Source parameters
*/
AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value );
AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values );
/*
* Get Source parameters
*/
AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values );
/*
* Source vector based playback calls
*/
/* Play, replay, or resume (if paused) a list of Sources */
AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids );
/* Stop a list of Sources */
AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids );
/* Rewind a list of Sources */
AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids );
/* Pause a list of Sources */
AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids );
/*
* Source based playback calls
*/
/* Play, replay, or resume a Source */
AL_API void AL_APIENTRY alSourcePlay( ALuint sid );
/* Stop a Source */
AL_API void AL_APIENTRY alSourceStop( ALuint sid );
/* Rewind a Source (set playback postiton to beginning) */
AL_API void AL_APIENTRY alSourceRewind( ALuint sid );
/* Pause a Source */
AL_API void AL_APIENTRY alSourcePause( ALuint sid );
/*
* Source Queuing
*/
AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids );
AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
/**
* BUFFER
* Buffer objects are storage space for sample data.
* Buffers are referred to by Sources. One Buffer can be used
* by multiple Sources.
*
* Properties include: -
*
* Frequency (Query only) AL_FREQUENCY ALint
* Size (Query only) AL_SIZE ALint
* Bits (Query only) AL_BITS ALint
* Channels (Query only) AL_CHANNELS ALint
*/
/* Create Buffer objects */
AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers );
/* Delete Buffer objects */
AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers );
/* Verify a handle is a valid Buffer */
AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint bid );
/* Specify the data to be copied into a buffer */
AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
/*
* Set Buffer parameters
*/
AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value );
AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values );
/*
* Get Buffer parameters
*/
AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values );
/*
* Global Parameters
*/
AL_API void AL_APIENTRY alDopplerFactor( ALfloat value );
AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value );
AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value );
AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel );
/*
* Pointer-to-function types, useful for dynamically getting AL entry points.
*/
typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability );
typedef void (AL_APIENTRY *LPALDISABLE)( ALenum capability );
typedef ALboolean (AL_APIENTRY *LPALISENABLED)( ALenum capability );
typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)( ALenum param );
typedef void (AL_APIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data );
typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)( ALenum param );
typedef ALint (AL_APIENTRY *LPALGETINTEGER)( ALenum param );
typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)( ALenum param );
typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)( ALenum param );
typedef ALenum (AL_APIENTRY *LPALGETERROR)( void );
typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname );
typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)( const ALchar* fname );
typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)( const ALchar* ename );
typedef void (AL_APIENTRY *LPALLISTENERF)( ALenum param, ALfloat value );
typedef void (AL_APIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALLISTENERI)( ALenum param, ALint value );
typedef void (AL_APIENTRY *LPALLISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALLISTENERIV)( ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERIV)( ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources );
typedef void (AL_APIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources );
typedef ALboolean (AL_APIENTRY *LPALISSOURCE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
typedef void (AL_APIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers );
typedef void (AL_APIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers );
typedef ALboolean (AL_APIENTRY *LPALISBUFFER)( ALuint bid );
typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)( ALfloat value );
typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)( ALfloat value );
typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)( ALfloat value );
typedef void (AL_APIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif /* AL_AL_H */

277
jni/OpenAL/alc.h Normal file
View File

@ -0,0 +1,277 @@
#ifndef AL_ALC_H
#define AL_ALC_H
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(AL_LIBTYPE_STATIC)
#define ALC_API
#elif defined(_WIN32) && !defined(_XBOX)
#if defined(AL_BUILD_LIBRARY)
#define ALC_API __declspec(dllexport)
#else
#define ALC_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define ALC_API __attribute__((visibility("protected")))
#else
#define ALC_API extern
#endif
#endif
#if defined(_WIN32)
#define ALC_APIENTRY __cdecl
#else
#define ALC_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are
* included for applications porting code from AL 1.0
*/
#define ALCAPI ALC_API
#define ALCAPIENTRY ALC_APIENTRY
#define ALC_INVALID 0
#define ALC_VERSION_0_1 1
typedef struct ALCdevice_struct ALCdevice;
typedef struct ALCcontext_struct ALCcontext;
/** 8-bit boolean */
typedef char ALCboolean;
/** character */
typedef char ALCchar;
/** signed 8-bit 2's complement integer */
typedef signed char ALCbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALCubyte;
/** signed 16-bit 2's complement integer */
typedef short ALCshort;
/** unsigned 16-bit integer */
typedef unsigned short ALCushort;
/** signed 32-bit 2's complement integer */
typedef int ALCint;
/** unsigned 32-bit integer */
typedef unsigned int ALCuint;
/** non-negative 32-bit binary integer size */
typedef int ALCsizei;
/** enumerated 32-bit value */
typedef int ALCenum;
/** 32-bit IEEE754 floating-point */
typedef float ALCfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALCdouble;
/** void type (for opaque pointers only) */
typedef void ALCvoid;
/* Enumerant values begin at column 50. No tabs. */
/* Boolean False. */
#define ALC_FALSE 0
/* Boolean True. */
#define ALC_TRUE 1
/**
* followed by <int> Hz
*/
#define ALC_FREQUENCY 0x1007
/**
* followed by <int> Hz
*/
#define ALC_REFRESH 0x1008
/**
* followed by AL_TRUE, AL_FALSE
*/
#define ALC_SYNC 0x1009
/**
* followed by <int> Num of requested Mono (3D) Sources
*/
#define ALC_MONO_SOURCES 0x1010
/**
* followed by <int> Num of requested Stereo Sources
*/
#define ALC_STEREO_SOURCES 0x1011
/**
* errors
*/
/**
* No error
*/
#define ALC_NO_ERROR ALC_FALSE
/**
* No device
*/
#define ALC_INVALID_DEVICE 0xA001
/**
* invalid context ID
*/
#define ALC_INVALID_CONTEXT 0xA002
/**
* bad enum
*/
#define ALC_INVALID_ENUM 0xA003
/**
* bad value
*/
#define ALC_INVALID_VALUE 0xA004
/**
* Out of memory.
*/
#define ALC_OUT_OF_MEMORY 0xA005
/**
* The Specifier string for default device
*/
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
#define ALC_DEVICE_SPECIFIER 0x1005
#define ALC_EXTENSIONS 0x1006
#define ALC_MAJOR_VERSION 0x1000
#define ALC_MINOR_VERSION 0x1001
#define ALC_ATTRIBUTES_SIZE 0x1002
#define ALC_ALL_ATTRIBUTES 0x1003
/**
* Capture extension
*/
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
#define ALC_CAPTURE_SAMPLES 0x312
/*
* Context Management
*/
ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist );
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context );
ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context );
ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void );
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context );
/*
* Device Management
*/
ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename );
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device );
/*
* Error support.
* Obtain the most recent Context error
*/
ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname );
ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname );
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname );
/*
* Query functions
*/
ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param );
ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
/*
* Capture functions
*/
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
/*
* Pointer-to-function types, useful for dynamically getting ALC entry points.
*/
typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void );
typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device );
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
}
#endif
#endif /* AL_ALC_H */

54
jni/OpenAL/build.mk Normal file
View File

@ -0,0 +1,54 @@
MODULE = System/OpenAL
CCFLAGS = \
-I$(SYSDIR) \
-I$(SYSDIR)/OpenAL/include \
-I$(SYSDIR)/OpenAL/OpenAL32/Include \
-DAL_BUILD_LIBRARY \
-DAL_ALEXT_PROTOTYPES \
-DVERDE_USE_REAL_FILE_IO \
OBJECTS = \
ifneq ($(OS), mac)
OBJECTS += \
OpenAL32/alAuxEffectSlot.o \
OpenAL32/alBuffer.o \
OpenAL32/alDatabuffer.o \
OpenAL32/alEffect.o \
OpenAL32/alError.o \
OpenAL32/alExtension.o \
OpenAL32/alFilter.o \
OpenAL32/alListener.o \
OpenAL32/alSource.o \
OpenAL32/alState.o \
OpenAL32/alThunk.o \
Alc/ALc.o \
Alc/alcConfig.o \
Alc/alcEcho.o \
Alc/alcModulator.o \
Alc/alcReverb.o \
Alc/alcRing.o \
Alc/alcThread.o \
Alc/ALu.o \
Alc/bs2b.o \
Alc/null.o \
Alc/panning.o \
Alc/mixer.o \
endif
ifeq ($(TARGET_OS), android)
OBJECTS += Alc/audiotrack.o
ifdef POST_FROYO
OBJECTS += Alc/opensles.o
endif
CCFLAGS += -I/Developer/AndroidNDK/platforms/android-9/arch-arm/usr/include
CCFLAGS += -DOPENAL_FIXED_POINT -DOPENAL_FIXED_POINT_SHIFT=16
endif
ifeq ($(OS), linux)
OBJECTS += Alc/oss.o
endif
include $(ROOTDIR)/module.mk

814
jni/OpenAL/include/AL/al.h Normal file
View File

@ -0,0 +1,814 @@
#ifndef AL_AL_H
#define AL_AL_H
#ifdef ANDROID
#include <android/log.h>
#ifndef LOGI
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"OpenAL",__VA_ARGS__)
#endif
#ifndef LOGE
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"OpenAL",__VA_ARGS__)
#endif
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(AL_LIBTYPE_STATIC)
#define AL_API
#elif defined(_WIN32) && !defined(_XBOX)
#if defined(AL_BUILD_LIBRARY)
#define AL_API __declspec(dllexport)
#else
#define AL_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define AL_API __attribute__((visibility("protected")))
#else
#define AL_API extern
#endif
#endif
#if defined(_WIN32)
#define AL_APIENTRY __cdecl
#else
#define AL_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The OPENAL, ALAPI, ALAPIENTRY, AL_INVALID, AL_ILLEGAL_ENUM, and
* AL_ILLEGAL_COMMAND macros are deprecated, but are included for
* applications porting code from AL 1.0
*/
#define OPENAL
#define ALAPI AL_API
#define ALAPIENTRY AL_APIENTRY
#define AL_INVALID (-1)
#define AL_ILLEGAL_ENUM AL_INVALID_ENUM
#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
#define AL_VERSION_1_0
#define AL_VERSION_1_1
/** 8-bit boolean */
typedef char ALboolean;
/** character */
typedef char ALchar;
/** signed 8-bit 2's complement integer */
typedef signed char ALbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALubyte;
/** signed 16-bit 2's complement integer */
typedef short ALshort;
/** unsigned 16-bit integer */
typedef unsigned short ALushort;
/** signed 32-bit 2's complement integer */
typedef int ALint;
/** unsigned 32-bit integer */
typedef unsigned int ALuint;
/** non-negative 32-bit binary integer size */
typedef int ALsizei;
/** enumerated 32-bit value */
typedef int ALenum;
/** 32-bit IEEE754 floating-point */
typedef float ALfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALdouble;
#ifdef OPENAL_FIXED_POINT
/** Types and Macros for fixed-point math */
#ifndef INT64_MAX
typedef long long int64_t;
#define INT64_MAX 9223372036854775807LL
#endif
#ifndef INT32_MAX
typedef int int32_t;
#define INT32_MAX 2147483647
#endif
// FIXME(apportable) make this int32_t
typedef int64_t ALfp;
typedef int64_t ALdfp;
#define ONE (1<<OPENAL_FIXED_POINT_SHIFT)
#define TWO (2<<OPENAL_FIXED_POINT_SHIFT)
#define float2ALfp(x) ((ALfp)((x) * (1<<OPENAL_FIXED_POINT_SHIFT) + ((x)>=0 ? 0.5 : -0.5)))
#define ALfp2float(x) ((float)(x) / (1<<OPENAL_FIXED_POINT_SHIFT))
#define double2ALdfp(x) ((ALdfp)((x) * (1<<OPENAL_FIXED_POINT_SHIFT) + ((x)>=0 ? 0.5 : -0.5)))
#define ALdfp2double(x) ((double)(x) / (1<<OPENAL_FIXED_POINT_SHIFT))
#define int2ALfp(x) ((ALfp)(x) << OPENAL_FIXED_POINT_SHIFT)
#define ALfp2int(x) ((ALint)((x) >> OPENAL_FIXED_POINT_SHIFT))
#define int2ALdfp(x) ((ALdfp)(x) << OPENAL_FIXED_POINT_SHIFT)
#define ALdfp2int(x) ((ALint)((x) >> OPENAL_FIXED_POINT_SHIFT))
#define ALfpMult(x,y) ((ALfp)((((int64_t)(x))*((int64_t)(y)))>>OPENAL_FIXED_POINT_SHIFT))
#define ALfpDiv(x,y) ((ALfp)(((int64_t)(x) << OPENAL_FIXED_POINT_SHIFT) / (y)))
#define ALdfpMult(x,y) ALfpMult(x,y)
#define ALdfpDiv(x,y) ALfpDiv(x,y)
#define __isnan(x) (0)
#define __cos(x) (float2ALfp(cos(ALfp2float(x))))
#define __sin(x) (float2ALfp(sin(ALfp2float(x))))
#define __log10(x) (float2ALfp(log10(ALfp2float(x))))
#define __atan(x) (float2ALfp(atan(ALfp2float(x))))
#define toALfpConst(x) ((x)*(1<<OPENAL_FIXED_POINT_SHIFT))
#else
typedef float ALfp;
typedef double ALdfp;
#define ONE (1)
#define TWO (2)
#define float2ALfp(x) (x)
#define ALfp2float(x) (x)
#define double2ALdfp(x) (x)
#define ALdfp2double(x) (x)
#define int2ALfp(x) ((ALfp)(x))
#define ALfp2int(x) ((ALint)(x))
#define int2ALdfp(x) ((ALdfp)(x))
#define ALdfp2int(x) ((ALint)(x))
#define ALfpMult(x,y) ((x)*(y))
#define ALfpDiv(x,y) ((x)/(y))
#define ALdfpMult(x,y) ALfpMult((x),(y))
#define ALdfpDiv(x,y) ALfpDiv((x),(y))
#define __isnan(x) (0)
#define __cos(x) cos((x))
#define __sin(x) sin((x))
#define __log10(x) log10((x))
#define __atan(x) atan((x))
#define toALfpConst(x) (x)
#endif
/** void type (for opaque pointers only) */
typedef void ALvoid;
/* Enumerant values begin at column 50. No tabs. */
/* "no distance model" or "no buffer" */
#define AL_NONE 0
/* Boolean False. */
#define AL_FALSE 0
/** Boolean True. */
#define AL_TRUE 1
/** Indicate Source has relative coordinates. */
#define AL_SOURCE_RELATIVE 0x202
/**
* Directional source, inner cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_INNER_ANGLE 0x1001
/**
* Directional source, outer cone angle, in degrees.
* Range: [0-360]
* Default: 360
*/
#define AL_CONE_OUTER_ANGLE 0x1002
/**
* Specify the pitch to be applied at source.
* Range: [0.5-2.0]
* Default: 1.0
*/
#define AL_PITCH 0x1003
/**
* Specify the current location in three dimensional space.
* OpenAL, like OpenGL, uses a right handed coordinate system,
* where in a frontal default view X (thumb) points right,
* Y points up (index finger), and Z points towards the
* viewer/camera (middle finger).
* To switch from a left handed coordinate system, flip the
* sign on the Z coordinate.
* Listener position is always in the world coordinate system.
*/
#define AL_POSITION 0x1004
/** Specify the current direction. */
#define AL_DIRECTION 0x1005
/** Specify the current velocity in three dimensional space. */
#define AL_VELOCITY 0x1006
/**
* Indicate whether source is looping.
* Type: ALboolean?
* Range: [AL_TRUE, AL_FALSE]
* Default: FALSE.
*/
#define AL_LOOPING 0x1007
/**
* Indicate the buffer to provide sound samples.
* Type: ALuint.
* Range: any valid Buffer id.
*/
#define AL_BUFFER 0x1009
/**
* Indicate the gain (volume amplification) applied.
* Type: ALfloat.
* Range: ]0.0- ]
* A value of 1.0 means un-attenuated/unchanged.
* Each division by 2 equals an attenuation of -6dB.
* Each multiplicaton with 2 equals an amplification of +6dB.
* A value of 0.0 is meaningless with respect to a logarithmic
* scale; it is interpreted as zero volume - the channel
* is effectively disabled.
*/
#define AL_GAIN 0x100A
/*
* Indicate minimum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MIN_GAIN 0x100D
/**
* Indicate maximum source attenuation
* Type: ALfloat
* Range: [0.0 - 1.0]
*
* Logarthmic
*/
#define AL_MAX_GAIN 0x100E
/**
* Indicate listener orientation.
*
* at/up
*/
#define AL_ORIENTATION 0x100F
/**
* Source state information.
*/
#define AL_SOURCE_STATE 0x1010
#define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013
#define AL_STOPPED 0x1014
/**
* Buffer Queue params
*/
#define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016
/**
* Source buffer position information
*/
#define AL_SEC_OFFSET 0x1024
#define AL_SAMPLE_OFFSET 0x1025
#define AL_BYTE_OFFSET 0x1026
/*
* Source type (Static, Streaming or undetermined)
* Source is Static if a Buffer has been attached using AL_BUFFER
* Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
* Source is undetermined when it has the NULL buffer attached
*/
#define AL_SOURCE_TYPE 0x1027
#define AL_STATIC 0x1028
#define AL_STREAMING 0x1029
#define AL_UNDETERMINED 0x1030
/** Sound samples: format specifier. */
#define AL_FORMAT_MONO8 0x1100
#define AL_FORMAT_MONO16 0x1101
#define AL_FORMAT_STEREO8 0x1102
#define AL_FORMAT_STEREO16 0x1103
/**
* source specific reference distance
* Type: ALfloat
* Range: 0.0 - +inf
*
* At 0.0, no distance attenuation occurs. Default is
* 1.0.
*/
#define AL_REFERENCE_DISTANCE 0x1020
/**
* source specific rolloff factor
* Type: ALfloat
* Range: 0.0 - +inf
*
*/
#define AL_ROLLOFF_FACTOR 0x1021
/**
* Directional source, outer cone gain.
*
* Default: 0.0
* Range: [0.0 - 1.0]
* Logarithmic
*/
#define AL_CONE_OUTER_GAIN 0x1022
/**
* Indicate distance above which sources are not
* attenuated using the inverse clamped distance model.
*
* Default: +inf
* Type: ALfloat
* Range: 0.0 - +inf
*/
#define AL_MAX_DISTANCE 0x1023
/**
* Sound samples: frequency, in units of Hertz [Hz].
* This is the number of samples per second. Half of the
* sample frequency marks the maximum significant
* frequency component.
*/
#define AL_FREQUENCY 0x2001
#define AL_BITS 0x2002
#define AL_CHANNELS 0x2003
#define AL_SIZE 0x2004
/**
* Buffer state.
*
* Not supported for public use (yet).
*/
#define AL_UNUSED 0x2010
#define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012
/** Errors: No Error. */
#define AL_NO_ERROR AL_FALSE
/**
* Invalid Name paramater passed to AL call.
*/
#define AL_INVALID_NAME 0xA001
/**
* Invalid parameter passed to AL call.
*/
#define AL_INVALID_ENUM 0xA002
/**
* Invalid enum parameter value.
*/
#define AL_INVALID_VALUE 0xA003
/**
* Illegal call.
*/
#define AL_INVALID_OPERATION 0xA004
/**
* No mojo.
*/
#define AL_OUT_OF_MEMORY 0xA005
/** Context strings: Vendor Name. */
#define AL_VENDOR 0xB001
#define AL_VERSION 0xB002
#define AL_RENDERER 0xB003
#define AL_EXTENSIONS 0xB004
/** Global tweakage. */
/**
* Doppler scale. Default 1.0
*/
#define AL_DOPPLER_FACTOR 0xC000
/**
* Tweaks speed of propagation.
*/
#define AL_DOPPLER_VELOCITY 0xC001
/**
* Speed of Sound in units per second
*/
#define AL_SPEED_OF_SOUND 0xC003
/**
* Distance models
*
* used in conjunction with DistanceModel
*
* implicit: NONE, which disances distance attenuation.
*/
#define AL_DISTANCE_MODEL 0xD000
#define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
#define AL_LINEAR_DISTANCE 0xD003
#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
#define AL_EXPONENT_DISTANCE 0xD005
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
/*
* Renderer State management
*/
AL_API void AL_APIENTRY alEnable( ALenum capability );
AL_API void AL_APIENTRY alDisable( ALenum capability );
AL_API ALboolean AL_APIENTRY alIsEnabled( ALenum capability );
/*
* State retrieval
*/
AL_API const ALchar* AL_APIENTRY alGetString( ALenum param );
AL_API void AL_APIENTRY alGetBooleanv( ALenum param, ALboolean* data );
AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data );
AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data );
AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data );
AL_API ALboolean AL_APIENTRY alGetBoolean( ALenum param );
AL_API ALint AL_APIENTRY alGetInteger( ALenum param );
AL_API ALfloat AL_APIENTRY alGetFloat( ALenum param );
AL_API ALdouble AL_APIENTRY alGetDouble( ALenum param );
/*
* Error support.
* Obtain the most recent error generated in the AL state machine.
*/
AL_API ALenum AL_APIENTRY alGetError( void );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
AL_API ALboolean AL_APIENTRY alIsExtensionPresent( const ALchar* extname );
AL_API void* AL_APIENTRY alGetProcAddress( const ALchar* fname );
AL_API ALenum AL_APIENTRY alGetEnumValue( const ALchar* ename );
/*
* LISTENER
* Listener represents the location and orientation of the
* 'user' in 3D-space.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors)
*/
/*
* Set Listener parameters
*/
AL_API void AL_APIENTRY alListenerf( ALenum param, ALfloat value );
AL_API void AL_APIENTRY alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alListenerfv( ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alListeneri( ALenum param, ALint value );
AL_API void AL_APIENTRY alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alListeneriv( ALenum param, const ALint* values );
/*
* Get Listener parameters
*/
AL_API void AL_APIENTRY alGetListenerf( ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
AL_API void AL_APIENTRY alGetListenerfv( ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetListeneri( ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
AL_API void AL_APIENTRY alGetListeneriv( ALenum param, ALint* values );
/**
* SOURCE
* Sources represent individual sound objects in 3D-space.
* Sources take the PCM data provided in the specified Buffer,
* apply Source-specific modifications, and then
* submit them to be mixed according to spatial arrangement etc.
*
* Properties include: -
*
* Gain AL_GAIN ALfloat
* Min Gain AL_MIN_GAIN ALfloat
* Max Gain AL_MAX_GAIN ALfloat
* Position AL_POSITION ALfloat[3]
* Velocity AL_VELOCITY ALfloat[3]
* Direction AL_DIRECTION ALfloat[3]
* Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE)
* Reference Distance AL_REFERENCE_DISTANCE ALfloat
* Max Distance AL_MAX_DISTANCE ALfloat
* RollOff Factor AL_ROLLOFF_FACTOR ALfloat
* Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat
* Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat
* Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat
* Pitch AL_PITCH ALfloat
* Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE)
* MS Offset AL_MSEC_OFFSET ALint or ALfloat
* Byte Offset AL_BYTE_OFFSET ALint or ALfloat
* Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat
* Attached Buffer AL_BUFFER ALint
* State (Query only) AL_SOURCE_STATE ALint
* Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint
* Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint
*/
/* Create Source objects */
AL_API void AL_APIENTRY alGenSources( ALsizei n, ALuint* sources );
/* Delete Source objects */
AL_API void AL_APIENTRY alDeleteSources( ALsizei n, const ALuint* sources );
/* Verify a handle is a valid Source */
AL_API ALboolean AL_APIENTRY alIsSource( ALuint sid );
/*
* Set Source parameters
*/
AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value );
AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values );
/*
* Get Source parameters
*/
AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values );
/*
* Source vector based playback calls
*/
/* Play, replay, or resume (if paused) a list of Sources */
AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids );
/* Stop a list of Sources */
AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids );
/* Rewind a list of Sources */
AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids );
/* Pause a list of Sources */
AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids );
/*
* Source based playback calls
*/
/* Play, replay, or resume a Source */
AL_API void AL_APIENTRY alSourcePlay( ALuint sid );
/* Stop a Source */
AL_API void AL_APIENTRY alSourceStop( ALuint sid );
/* Rewind a Source (set playback postiton to beginning) */
AL_API void AL_APIENTRY alSourceRewind( ALuint sid );
/* Pause a Source */
AL_API void AL_APIENTRY alSourcePause( ALuint sid );
/*
* Source Queuing
*/
AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids );
AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
/**
* BUFFER
* Buffer objects are storage space for sample data.
* Buffers are referred to by Sources. One Buffer can be used
* by multiple Sources.
*
* Properties include: -
*
* Frequency (Query only) AL_FREQUENCY ALint
* Size (Query only) AL_SIZE ALint
* Bits (Query only) AL_BITS ALint
* Channels (Query only) AL_CHANNELS ALint
*/
/* Create Buffer objects */
AL_API void AL_APIENTRY alGenBuffers( ALsizei n, ALuint* buffers );
/* Delete Buffer objects */
AL_API void AL_APIENTRY alDeleteBuffers( ALsizei n, const ALuint* buffers );
/* Verify a handle is a valid Buffer */
AL_API ALboolean AL_APIENTRY alIsBuffer( ALuint bid );
/* Specify the data to be copied into a buffer */
AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
/*
* Set Buffer parameters
*/
AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value );
AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values );
AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value );
AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values );
/*
* Get Buffer parameters
*/
AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value );
AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values );
AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value );
AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values );
/*
* Global Parameters
*/
AL_API void AL_APIENTRY alDopplerFactor( ALfloat value );
AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value );
AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value );
AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel );
/*
* Pointer-to-function types, useful for dynamically getting AL entry points.
*/
typedef void (AL_APIENTRY *LPALENABLE)( ALenum capability );
typedef void (AL_APIENTRY *LPALDISABLE)( ALenum capability );
typedef ALboolean (AL_APIENTRY *LPALISENABLED)( ALenum capability );
typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)( ALenum param );
typedef void (AL_APIENTRY *LPALGETBOOLEANV)( ALenum param, ALboolean* data );
typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)( ALenum param );
typedef ALint (AL_APIENTRY *LPALGETINTEGER)( ALenum param );
typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)( ALenum param );
typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)( ALenum param );
typedef ALenum (AL_APIENTRY *LPALGETERROR)( void );
typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar* extname );
typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)( const ALchar* fname );
typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)( const ALchar* ename );
typedef void (AL_APIENTRY *LPALLISTENERF)( ALenum param, ALfloat value );
typedef void (AL_APIENTRY *LPALLISTENER3F)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALLISTENERFV)( ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALLISTENERI)( ALenum param, ALint value );
typedef void (AL_APIENTRY *LPALLISTENER3I)( ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALLISTENERIV)( ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETLISTENERF)( ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3F)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERFV)( ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETLISTENERI)( ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETLISTENER3I)( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
typedef void (AL_APIENTRY *LPALGETLISTENERIV)( ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALGENSOURCES)( ALsizei n, ALuint* sources );
typedef void (AL_APIENTRY *LPALDELETESOURCES)( ALsizei n, const ALuint* sources );
typedef ALboolean (AL_APIENTRY *LPALISSOURCE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid );
typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
typedef void (AL_APIENTRY *LPALGENBUFFERS)( ALsizei n, ALuint* buffers );
typedef void (AL_APIENTRY *LPALDELETEBUFFERS)( ALsizei n, const ALuint* buffers );
typedef ALboolean (AL_APIENTRY *LPALISBUFFER)( ALuint bid );
typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value);
typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values );
typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value);
typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values );
typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values );
typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, ALenum param, ALint* values );
typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)( ALfloat value );
typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)( ALfloat value );
typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)( ALfloat value );
typedef void (AL_APIENTRY *LPALDISTANCEMODEL)( ALenum distanceModel );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
} /* extern "C" */
#endif
#endif /* AL_AL_H */

277
jni/OpenAL/include/AL/alc.h Normal file
View File

@ -0,0 +1,277 @@
#ifndef AL_ALC_H
#define AL_ALC_H
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(AL_LIBTYPE_STATIC)
#define ALC_API
#elif defined(_WIN32) && !defined(_XBOX)
#if defined(AL_BUILD_LIBRARY)
#define ALC_API __declspec(dllexport)
#else
#define ALC_API __declspec(dllimport)
#endif
#else
#if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
#define ALC_API __attribute__((visibility("protected")))
#else
#define ALC_API extern
#endif
#endif
#if defined(_WIN32)
#define ALC_APIENTRY __cdecl
#else
#define ALC_APIENTRY
#endif
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export on
#endif
/*
* The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are
* included for applications porting code from AL 1.0
*/
#define ALCAPI ALC_API
#define ALCAPIENTRY ALC_APIENTRY
#define ALC_INVALID 0
#define ALC_VERSION_0_1 1
typedef struct ALCdevice_struct ALCdevice;
typedef struct ALCcontext_struct ALCcontext;
/** 8-bit boolean */
typedef char ALCboolean;
/** character */
typedef char ALCchar;
/** signed 8-bit 2's complement integer */
typedef signed char ALCbyte;
/** unsigned 8-bit integer */
typedef unsigned char ALCubyte;
/** signed 16-bit 2's complement integer */
typedef short ALCshort;
/** unsigned 16-bit integer */
typedef unsigned short ALCushort;
/** signed 32-bit 2's complement integer */
typedef int ALCint;
/** unsigned 32-bit integer */
typedef unsigned int ALCuint;
/** non-negative 32-bit binary integer size */
typedef int ALCsizei;
/** enumerated 32-bit value */
typedef int ALCenum;
/** 32-bit IEEE754 floating-point */
typedef float ALCfloat;
/** 64-bit IEEE754 floating-point */
typedef double ALCdouble;
/** void type (for opaque pointers only) */
typedef void ALCvoid;
/* Enumerant values begin at column 50. No tabs. */
/* Boolean False. */
#define ALC_FALSE 0
/* Boolean True. */
#define ALC_TRUE 1
/**
* followed by <int> Hz
*/
#define ALC_FREQUENCY 0x1007
/**
* followed by <int> Hz
*/
#define ALC_REFRESH 0x1008
/**
* followed by AL_TRUE, AL_FALSE
*/
#define ALC_SYNC 0x1009
/**
* followed by <int> Num of requested Mono (3D) Sources
*/
#define ALC_MONO_SOURCES 0x1010
/**
* followed by <int> Num of requested Stereo Sources
*/
#define ALC_STEREO_SOURCES 0x1011
/**
* errors
*/
/**
* No error
*/
#define ALC_NO_ERROR ALC_FALSE
/**
* No device
*/
#define ALC_INVALID_DEVICE 0xA001
/**
* invalid context ID
*/
#define ALC_INVALID_CONTEXT 0xA002
/**
* bad enum
*/
#define ALC_INVALID_ENUM 0xA003
/**
* bad value
*/
#define ALC_INVALID_VALUE 0xA004
/**
* Out of memory.
*/
#define ALC_OUT_OF_MEMORY 0xA005
/**
* The Specifier string for default device
*/
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
#define ALC_DEVICE_SPECIFIER 0x1005
#define ALC_EXTENSIONS 0x1006
#define ALC_MAJOR_VERSION 0x1000
#define ALC_MINOR_VERSION 0x1001
#define ALC_ATTRIBUTES_SIZE 0x1002
#define ALC_ALL_ATTRIBUTES 0x1003
/**
* Capture extension
*/
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
#define ALC_CAPTURE_SAMPLES 0x312
/*
* Context Management
*/
ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist );
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent( ALCcontext *context );
ALC_API void ALC_APIENTRY alcProcessContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcSuspendContext( ALCcontext *context );
ALC_API void ALC_APIENTRY alcDestroyContext( ALCcontext *context );
ALC_API ALCcontext * ALC_APIENTRY alcGetCurrentContext( void );
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice( ALCcontext *context );
/*
* Device Management
*/
ALC_API ALCdevice * ALC_APIENTRY alcOpenDevice( const ALCchar *devicename );
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice( ALCdevice *device );
/*
* Error support.
* Obtain the most recent Context error
*/
ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device );
/*
* Extension support.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname );
ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname );
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname );
/*
* Query functions
*/
ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param );
ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
/*
* Capture functions
*/
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStart( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureStop( ALCdevice *device );
ALC_API void ALC_APIENTRY alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
/*
* Pointer-to-function types, useful for dynamically getting ALC entry points.
*/
typedef ALCcontext * (ALC_APIENTRY *LPALCCREATECONTEXT) (ALCdevice *device, const ALCint *attrlist);
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)( ALCcontext *context );
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)( ALCcontext *context );
typedef ALCcontext * (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)( void );
typedef ALCdevice * (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)( ALCcontext *context );
typedef ALCdevice * (ALC_APIENTRY *LPALCOPENDEVICE)( const ALCchar *devicename );
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)( ALCdevice *device );
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)( ALCdevice *device );
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)( ALCdevice *device, const ALCchar *extname );
typedef void * (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname );
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname );
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)( ALCdevice *device, ALCenum param );
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *dest );
typedef ALCdevice * (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)( ALCdevice *device );
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
#pragma export off
#endif
#if defined(__cplusplus)
}
#endif
#endif /* AL_ALC_H */

View File

@ -0,0 +1,165 @@
/**
* 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
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AL_LOKI_IMA_ADPCM_format
#define AL_LOKI_IMA_ADPCM_format 1
#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
#define AL_FORMAT_IMA_ADPCM_STEREO16_EXT 0x10001
#endif
#ifndef AL_LOKI_WAVE_format
#define AL_LOKI_WAVE_format 1
#define AL_FORMAT_WAVE_EXT 0x10002
#endif
#ifndef AL_EXT_vorbis
#define AL_EXT_vorbis 1
#define AL_FORMAT_VORBIS_EXT 0x10003
#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_float32
#define AL_EXT_float32 1
#define AL_FORMAT_MONO_FLOAT32 0x10010
#define AL_FORMAT_STEREO_FLOAT32 0x10011
#endif
#ifndef AL_EXT_double
#define AL_EXT_double 1
#define AL_FORMAT_MONO_DOUBLE_EXT 0x10012
#define AL_FORMAT_STEREO_DOUBLE_EXT 0x10013
#endif
#ifndef ALC_LOKI_audio_channel
#define ALC_LOKI_audio_channel 1
#define ALC_CHAN_MAIN_LOKI 0x500001
#define ALC_CHAN_PCM_LOKI 0x500002
#define ALC_CHAN_CD_LOKI 0x500003
#endif
#ifndef ALC_ENUMERATE_ALL_EXT
#define ALC_ENUMERATE_ALL_EXT 1
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
#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_MULAW_MCFORMATS
#define AL_EXT_MULAW_MCFORMATS 1
#define AL_FORMAT_MONO_MULAW 0x10014
#define AL_FORMAT_STEREO_MULAW 0x10015
#define AL_FORMAT_QUAD_MULAW 0x10021
#define AL_FORMAT_REAR_MULAW 0x10022
#define AL_FORMAT_51CHN_MULAW 0x10023
#define AL_FORMAT_61CHN_MULAW 0x10024
#define AL_FORMAT_71CHN_MULAW 0x10025
#endif
#ifndef AL_EXT_IMA4
#define AL_EXT_IMA4 1
#define AL_FORMAT_MONO_IMA4 0x1300
#define AL_FORMAT_STEREO_IMA4 0x1301
#endif
#ifndef AL_EXT_STATIC_BUFFER
#define AL_EXT_STATIC_BUFFER 1
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq);
#endif
#endif
#ifndef ALC_EXT_EFX
#define ALC_EXT_EFX 1
#include "efx.h"
#endif
#ifndef ALC_EXT_disconnect
#define ALC_EXT_disconnect 1
#define ALC_CONNECTED 0x313
#endif
#ifndef ALC_EXT_thread_local_context
#define ALC_EXT_thread_local_context 1
typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context);
typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void);
#ifdef AL_ALEXT_PROTOTYPES
ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context);
ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
#endif
#endif
#ifndef AL_EXT_source_distance_model
#define AL_EXT_source_distance_model 1
#define AL_SOURCE_DISTANCE_MODEL 0x200
#endif
#ifndef AL_SOFT_buffer_sub_data
#define AL_SOFT_buffer_sub_data 1
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length);
#endif
#endif
#ifndef AL_SOFT_loop_points
#define AL_SOFT_loop_points 1
#define AL_LOOP_POINTS_SOFT 0x2015
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,3 @@
/* The tokens that would be defined here are already defined in efx.h. This
* empty file is here to provide compatibility with Windows-based projects
* that would include it. */

758
jni/OpenAL/include/AL/efx.h Normal file
View File

@ -0,0 +1,758 @@
#ifndef AL_EFX_H
#define AL_EFX_H
#ifdef __cplusplus
extern "C" {
#endif
#define ALC_EXT_EFX_NAME "ALC_EXT_EFX"
#define ALC_EFX_MAJOR_VERSION 0x20001
#define ALC_EFX_MINOR_VERSION 0x20002
#define ALC_MAX_AUXILIARY_SENDS 0x20003
/* Listener properties. */
#define AL_METERS_PER_UNIT 0x20004
/* Source properties. */
#define AL_DIRECT_FILTER 0x20005
#define AL_AUXILIARY_SEND_FILTER 0x20006
#define AL_AIR_ABSORPTION_FACTOR 0x20007
#define AL_ROOM_ROLLOFF_FACTOR 0x20008
#define AL_CONE_OUTER_GAINHF 0x20009
#define AL_DIRECT_FILTER_GAINHF_AUTO 0x2000A
#define AL_AUXILIARY_SEND_FILTER_GAIN_AUTO 0x2000B
#define AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO 0x2000C
/* Effect properties. */
/* Reverb effect parameters */
#define AL_REVERB_DENSITY 0x0001
#define AL_REVERB_DIFFUSION 0x0002
#define AL_REVERB_GAIN 0x0003
#define AL_REVERB_GAINHF 0x0004
#define AL_REVERB_DECAY_TIME 0x0005
#define AL_REVERB_DECAY_HFRATIO 0x0006
#define AL_REVERB_REFLECTIONS_GAIN 0x0007
#define AL_REVERB_REFLECTIONS_DELAY 0x0008
#define AL_REVERB_LATE_REVERB_GAIN 0x0009
#define AL_REVERB_LATE_REVERB_DELAY 0x000A
#define AL_REVERB_AIR_ABSORPTION_GAINHF 0x000B
#define AL_REVERB_ROOM_ROLLOFF_FACTOR 0x000C
#define AL_REVERB_DECAY_HFLIMIT 0x000D
/* EAX Reverb effect parameters */
#define AL_EAXREVERB_DENSITY 0x0001
#define AL_EAXREVERB_DIFFUSION 0x0002
#define AL_EAXREVERB_GAIN 0x0003
#define AL_EAXREVERB_GAINHF 0x0004
#define AL_EAXREVERB_GAINLF 0x0005
#define AL_EAXREVERB_DECAY_TIME 0x0006
#define AL_EAXREVERB_DECAY_HFRATIO 0x0007
#define AL_EAXREVERB_DECAY_LFRATIO 0x0008
#define AL_EAXREVERB_REFLECTIONS_GAIN 0x0009
#define AL_EAXREVERB_REFLECTIONS_DELAY 0x000A
#define AL_EAXREVERB_REFLECTIONS_PAN 0x000B
#define AL_EAXREVERB_LATE_REVERB_GAIN 0x000C
#define AL_EAXREVERB_LATE_REVERB_DELAY 0x000D
#define AL_EAXREVERB_LATE_REVERB_PAN 0x000E
#define AL_EAXREVERB_ECHO_TIME 0x000F
#define AL_EAXREVERB_ECHO_DEPTH 0x0010
#define AL_EAXREVERB_MODULATION_TIME 0x0011
#define AL_EAXREVERB_MODULATION_DEPTH 0x0012
#define AL_EAXREVERB_AIR_ABSORPTION_GAINHF 0x0013
#define AL_EAXREVERB_HFREFERENCE 0x0014
#define AL_EAXREVERB_LFREFERENCE 0x0015
#define AL_EAXREVERB_ROOM_ROLLOFF_FACTOR 0x0016
#define AL_EAXREVERB_DECAY_HFLIMIT 0x0017
/* Chorus effect parameters */
#define AL_CHORUS_WAVEFORM 0x0001
#define AL_CHORUS_PHASE 0x0002
#define AL_CHORUS_RATE 0x0003
#define AL_CHORUS_DEPTH 0x0004
#define AL_CHORUS_FEEDBACK 0x0005
#define AL_CHORUS_DELAY 0x0006
/* Distortion effect parameters */
#define AL_DISTORTION_EDGE 0x0001
#define AL_DISTORTION_GAIN 0x0002
#define AL_DISTORTION_LOWPASS_CUTOFF 0x0003
#define AL_DISTORTION_EQCENTER 0x0004
#define AL_DISTORTION_EQBANDWIDTH 0x0005
/* Echo effect parameters */
#define AL_ECHO_DELAY 0x0001
#define AL_ECHO_LRDELAY 0x0002
#define AL_ECHO_DAMPING 0x0003
#define AL_ECHO_FEEDBACK 0x0004
#define AL_ECHO_SPREAD 0x0005
/* Flanger effect parameters */
#define AL_FLANGER_WAVEFORM 0x0001
#define AL_FLANGER_PHASE 0x0002
#define AL_FLANGER_RATE 0x0003
#define AL_FLANGER_DEPTH 0x0004
#define AL_FLANGER_FEEDBACK 0x0005
#define AL_FLANGER_DELAY 0x0006
/* Frequency shifter effect parameters */
#define AL_FREQUENCY_SHIFTER_FREQUENCY 0x0001
#define AL_FREQUENCY_SHIFTER_LEFT_DIRECTION 0x0002
#define AL_FREQUENCY_SHIFTER_RIGHT_DIRECTION 0x0003
/* Vocal morpher effect parameters */
#define AL_VOCAL_MORPHER_PHONEMEA 0x0001
#define AL_VOCAL_MORPHER_PHONEMEA_COARSE_TUNING 0x0002
#define AL_VOCAL_MORPHER_PHONEMEB 0x0003
#define AL_VOCAL_MORPHER_PHONEMEB_COARSE_TUNING 0x0004
#define AL_VOCAL_MORPHER_WAVEFORM 0x0005
#define AL_VOCAL_MORPHER_RATE 0x0006
/* Pitchshifter effect parameters */
#define AL_PITCH_SHIFTER_COARSE_TUNE 0x0001
#define AL_PITCH_SHIFTER_FINE_TUNE 0x0002
/* Ringmodulator effect parameters */
#define AL_RING_MODULATOR_FREQUENCY 0x0001
#define AL_RING_MODULATOR_HIGHPASS_CUTOFF 0x0002
#define AL_RING_MODULATOR_WAVEFORM 0x0003
/* Autowah effect parameters */
#define AL_AUTOWAH_ATTACK_TIME 0x0001
#define AL_AUTOWAH_RELEASE_TIME 0x0002
#define AL_AUTOWAH_RESONANCE 0x0003
#define AL_AUTOWAH_PEAK_GAIN 0x0004
/* Compressor effect parameters */
#define AL_COMPRESSOR_ONOFF 0x0001
/* Equalizer effect parameters */
#define AL_EQUALIZER_LOW_GAIN 0x0001
#define AL_EQUALIZER_LOW_CUTOFF 0x0002
#define AL_EQUALIZER_MID1_GAIN 0x0003
#define AL_EQUALIZER_MID1_CENTER 0x0004
#define AL_EQUALIZER_MID1_WIDTH 0x0005
#define AL_EQUALIZER_MID2_GAIN 0x0006
#define AL_EQUALIZER_MID2_CENTER 0x0007
#define AL_EQUALIZER_MID2_WIDTH 0x0008
#define AL_EQUALIZER_HIGH_GAIN 0x0009
#define AL_EQUALIZER_HIGH_CUTOFF 0x000A
/* Effect type */
#define AL_EFFECT_FIRST_PARAMETER 0x0000
#define AL_EFFECT_LAST_PARAMETER 0x8000
#define AL_EFFECT_TYPE 0x8001
/* Effect types, used with the AL_EFFECT_TYPE property */
#define AL_EFFECT_NULL 0x0000
#define AL_EFFECT_REVERB 0x0001
#define AL_EFFECT_CHORUS 0x0002
#define AL_EFFECT_DISTORTION 0x0003
#define AL_EFFECT_ECHO 0x0004
#define AL_EFFECT_FLANGER 0x0005
#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
#define AL_EFFECT_VOCAL_MORPHER 0x0007
#define AL_EFFECT_PITCH_SHIFTER 0x0008
#define AL_EFFECT_RING_MODULATOR 0x0009
#define AL_EFFECT_AUTOWAH 0x000A
#define AL_EFFECT_COMPRESSOR 0x000B
#define AL_EFFECT_EQUALIZER 0x000C
#define AL_EFFECT_EAXREVERB 0x8000
/* Auxiliary Effect Slot properties. */
#define AL_EFFECTSLOT_EFFECT 0x0001
#define AL_EFFECTSLOT_GAIN 0x0002
#define AL_EFFECTSLOT_AUXILIARY_SEND_AUTO 0x0003
/* NULL Auxiliary Slot ID to disable a source send. */
#define AL_EFFECTSLOT_NULL 0x0000
/* Filter properties. */
/* Lowpass filter parameters */
#define AL_LOWPASS_GAIN 0x0001
#define AL_LOWPASS_GAINHF 0x0002
/* Highpass filter parameters */
#define AL_HIGHPASS_GAIN 0x0001
#define AL_HIGHPASS_GAINLF 0x0002
/* Bandpass filter parameters */
#define AL_BANDPASS_GAIN 0x0001
#define AL_BANDPASS_GAINLF 0x0002
#define AL_BANDPASS_GAINHF 0x0003
/* Filter type */
#define AL_FILTER_FIRST_PARAMETER 0x0000
#define AL_FILTER_LAST_PARAMETER 0x8000
#define AL_FILTER_TYPE 0x8001
/* Filter types, used with the AL_FILTER_TYPE property */
#define AL_FILTER_NULL 0x0000
#define AL_FILTER_LOWPASS 0x0001
#define AL_FILTER_HIGHPASS 0x0002
#define AL_FILTER_BANDPASS 0x0003
/* Effect object function types. */
typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*);
/* Filter object function types. */
typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*);
/* Auxiliary Effect Slot object function types. */
typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*);
typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*);
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*);
#ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects);
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, ALuint *effects);
AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect);
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters);
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, ALuint *filters);
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter);
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots);
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue);
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues);
#endif
/* Filter ranges and defaults. */
/* Lowpass filter */
#define LOWPASS_MIN_GAIN (0.0f)
#define LOWPASS_MAX_GAIN (1.0f)
#define LOWPASS_DEFAULT_GAIN (1.0f)
#define LOWPASS_MIN_GAINHF (0.0f)
#define LOWPASS_MAX_GAINHF (1.0f)
#define LOWPASS_DEFAULT_GAINHF (1.0f)
/* Highpass filter */
#define HIGHPASS_MIN_GAIN (0.0f)
#define HIGHPASS_MAX_GAIN (1.0f)
#define HIGHPASS_DEFAULT_GAIN (1.0f)
#define HIGHPASS_MIN_GAINLF (0.0f)
#define HIGHPASS_MAX_GAINLF (1.0f)
#define HIGHPASS_DEFAULT_GAINLF (1.0f)
/* Bandpass filter */
#define BANDPASS_MIN_GAIN (0.0f)
#define BANDPASS_MAX_GAIN (1.0f)
#define BANDPASS_DEFAULT_GAIN (1.0f)
#define BANDPASS_MIN_GAINHF (0.0f)
#define BANDPASS_MAX_GAINHF (1.0f)
#define BANDPASS_DEFAULT_GAINHF (1.0f)
#define BANDPASS_MIN_GAINLF (0.0f)
#define BANDPASS_MAX_GAINLF (1.0f)
#define BANDPASS_DEFAULT_GAINLF (1.0f)
/* Effect parameter ranges and defaults. */
/* Standard reverb effect */
#define AL_REVERB_MIN_DENSITY (0.0f)
#define AL_REVERB_MAX_DENSITY (1.0f)
#define AL_REVERB_DEFAULT_DENSITY (1.0f)
#define AL_REVERB_MIN_DIFFUSION (0.0f)
#define AL_REVERB_MAX_DIFFUSION (1.0f)
#define AL_REVERB_DEFAULT_DIFFUSION (1.0f)
#define AL_REVERB_MIN_GAIN (0.0f)
#define AL_REVERB_MAX_GAIN (1.0f)
#define AL_REVERB_DEFAULT_GAIN (0.32f)
#define AL_REVERB_MIN_GAINHF (0.0f)
#define AL_REVERB_MAX_GAINHF (1.0f)
#define AL_REVERB_DEFAULT_GAINHF (0.89f)
#define AL_REVERB_MIN_DECAY_TIME (0.1f)
#define AL_REVERB_MAX_DECAY_TIME (20.0f)
#define AL_REVERB_DEFAULT_DECAY_TIME (1.49f)
#define AL_REVERB_MIN_DECAY_HFRATIO (0.1f)
#define AL_REVERB_MAX_DECAY_HFRATIO (2.0f)
#define AL_REVERB_DEFAULT_DECAY_HFRATIO (0.83f)
#define AL_REVERB_MIN_REFLECTIONS_GAIN (0.0f)
#define AL_REVERB_MAX_REFLECTIONS_GAIN (3.16f)
#define AL_REVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
#define AL_REVERB_MIN_REFLECTIONS_DELAY (0.0f)
#define AL_REVERB_MAX_REFLECTIONS_DELAY (0.3f)
#define AL_REVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
#define AL_REVERB_MIN_LATE_REVERB_GAIN (0.0f)
#define AL_REVERB_MAX_LATE_REVERB_GAIN (10.0f)
#define AL_REVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
#define AL_REVERB_MIN_LATE_REVERB_DELAY (0.0f)
#define AL_REVERB_MAX_LATE_REVERB_DELAY (0.1f)
#define AL_REVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
#define AL_REVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
#define AL_REVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
#define AL_REVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
#define AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_REVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_REVERB_MIN_DECAY_HFLIMIT AL_FALSE
#define AL_REVERB_MAX_DECAY_HFLIMIT AL_TRUE
#define AL_REVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
/* EAX reverb effect */
#define AL_EAXREVERB_MIN_DENSITY (0.0f)
#define AL_EAXREVERB_MAX_DENSITY (1.0f)
#define AL_EAXREVERB_DEFAULT_DENSITY (1.0f)
#define AL_EAXREVERB_MIN_DIFFUSION (0.0f)
#define AL_EAXREVERB_MAX_DIFFUSION (1.0f)
#define AL_EAXREVERB_DEFAULT_DIFFUSION (1.0f)
#define AL_EAXREVERB_MIN_GAIN (0.0f)
#define AL_EAXREVERB_MAX_GAIN (1.0f)
#define AL_EAXREVERB_DEFAULT_GAIN (0.32f)
#define AL_EAXREVERB_MIN_GAINHF (0.0f)
#define AL_EAXREVERB_MAX_GAINHF (1.0f)
#define AL_EAXREVERB_DEFAULT_GAINHF (0.89f)
#define AL_EAXREVERB_MIN_GAINLF (0.0f)
#define AL_EAXREVERB_MAX_GAINLF (1.0f)
#define AL_EAXREVERB_DEFAULT_GAINLF (1.0f)
#define AL_EAXREVERB_MIN_DECAY_TIME (0.1f)
#define AL_EAXREVERB_MAX_DECAY_TIME (20.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_TIME (1.49f)
#define AL_EAXREVERB_MIN_DECAY_HFRATIO (0.1f)
#define AL_EAXREVERB_MAX_DECAY_HFRATIO (2.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_HFRATIO (0.83f)
#define AL_EAXREVERB_MIN_DECAY_LFRATIO (0.1f)
#define AL_EAXREVERB_MAX_DECAY_LFRATIO (2.0f)
#define AL_EAXREVERB_DEFAULT_DECAY_LFRATIO (1.0f)
#define AL_EAXREVERB_MIN_REFLECTIONS_GAIN (0.0f)
#define AL_EAXREVERB_MAX_REFLECTIONS_GAIN (3.16f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_GAIN (0.05f)
#define AL_EAXREVERB_MIN_REFLECTIONS_DELAY (0.0f)
#define AL_EAXREVERB_MAX_REFLECTIONS_DELAY (0.3f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_DELAY (0.007f)
#define AL_EAXREVERB_DEFAULT_REFLECTIONS_PAN_XYZ (0.0f)
#define AL_EAXREVERB_MIN_LATE_REVERB_GAIN (0.0f)
#define AL_EAXREVERB_MAX_LATE_REVERB_GAIN (10.0f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_GAIN (1.26f)
#define AL_EAXREVERB_MIN_LATE_REVERB_DELAY (0.0f)
#define AL_EAXREVERB_MAX_LATE_REVERB_DELAY (0.1f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_DELAY (0.011f)
#define AL_EAXREVERB_DEFAULT_LATE_REVERB_PAN_XYZ (0.0f)
#define AL_EAXREVERB_MIN_ECHO_TIME (0.075f)
#define AL_EAXREVERB_MAX_ECHO_TIME (0.25f)
#define AL_EAXREVERB_DEFAULT_ECHO_TIME (0.25f)
#define AL_EAXREVERB_MIN_ECHO_DEPTH (0.0f)
#define AL_EAXREVERB_MAX_ECHO_DEPTH (1.0f)
#define AL_EAXREVERB_DEFAULT_ECHO_DEPTH (0.0f)
#define AL_EAXREVERB_MIN_MODULATION_TIME (0.04f)
#define AL_EAXREVERB_MAX_MODULATION_TIME (4.0f)
#define AL_EAXREVERB_DEFAULT_MODULATION_TIME (0.25f)
#define AL_EAXREVERB_MIN_MODULATION_DEPTH (0.0f)
#define AL_EAXREVERB_MAX_MODULATION_DEPTH (1.0f)
#define AL_EAXREVERB_DEFAULT_MODULATION_DEPTH (0.0f)
#define AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF (0.892f)
#define AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF (1.0f)
#define AL_EAXREVERB_DEFAULT_AIR_ABSORPTION_GAINHF (0.994f)
#define AL_EAXREVERB_MIN_HFREFERENCE (1000.0f)
#define AL_EAXREVERB_MAX_HFREFERENCE (20000.0f)
#define AL_EAXREVERB_DEFAULT_HFREFERENCE (5000.0f)
#define AL_EAXREVERB_MIN_LFREFERENCE (20.0f)
#define AL_EAXREVERB_MAX_LFREFERENCE (1000.0f)
#define AL_EAXREVERB_DEFAULT_LFREFERENCE (250.0f)
#define AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_EAXREVERB_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_EAXREVERB_MIN_DECAY_HFLIMIT AL_FALSE
#define AL_EAXREVERB_MAX_DECAY_HFLIMIT AL_TRUE
#define AL_EAXREVERB_DEFAULT_DECAY_HFLIMIT AL_TRUE
/* Chorus effect */
#define AL_CHORUS_WAVEFORM_SINUSOID (0)
#define AL_CHORUS_WAVEFORM_TRIANGLE (1)
#define AL_CHORUS_MIN_WAVEFORM (0)
#define AL_CHORUS_MAX_WAVEFORM (1)
#define AL_CHORUS_DEFAULT_WAVEFORM (1)
#define AL_CHORUS_MIN_PHASE (-180)
#define AL_CHORUS_MAX_PHASE (180)
#define AL_CHORUS_DEFAULT_PHASE (90)
#define AL_CHORUS_MIN_RATE (0.0f)
#define AL_CHORUS_MAX_RATE (10.0f)
#define AL_CHORUS_DEFAULT_RATE (1.1f)
#define AL_CHORUS_MIN_DEPTH (0.0f)
#define AL_CHORUS_MAX_DEPTH (1.0f)
#define AL_CHORUS_DEFAULT_DEPTH (0.1f)
#define AL_CHORUS_MIN_FEEDBACK (-1.0f)
#define AL_CHORUS_MAX_FEEDBACK (1.0f)
#define AL_CHORUS_DEFAULT_FEEDBACK (0.25f)
#define AL_CHORUS_MIN_DELAY (0.0f)
#define AL_CHORUS_MAX_DELAY (0.016f)
#define AL_CHORUS_DEFAULT_DELAY (0.016f)
/* Distortion effect */
#define AL_DISTORTION_MIN_EDGE (0.0f)
#define AL_DISTORTION_MAX_EDGE (1.0f)
#define AL_DISTORTION_DEFAULT_EDGE (0.2f)
#define AL_DISTORTION_MIN_GAIN (0.01f)
#define AL_DISTORTION_MAX_GAIN (1.0f)
#define AL_DISTORTION_DEFAULT_GAIN (0.05f)
#define AL_DISTORTION_MIN_LOWPASS_CUTOFF (80.0f)
#define AL_DISTORTION_MAX_LOWPASS_CUTOFF (24000.0f)
#define AL_DISTORTION_DEFAULT_LOWPASS_CUTOFF (8000.0f)
#define AL_DISTORTION_MIN_EQCENTER (80.0f)
#define AL_DISTORTION_MAX_EQCENTER (24000.0f)
#define AL_DISTORTION_DEFAULT_EQCENTER (3600.0f)
#define AL_DISTORTION_MIN_EQBANDWIDTH (80.0f)
#define AL_DISTORTION_MAX_EQBANDWIDTH (24000.0f)
#define AL_DISTORTION_DEFAULT_EQBANDWIDTH (3600.0f)
/* Echo effect */
#define AL_ECHO_MIN_DELAY (0.0f)
#define AL_ECHO_MAX_DELAY (0.207f)
#define AL_ECHO_DEFAULT_DELAY (0.1f)
#define AL_ECHO_MIN_LRDELAY (0.0f)
#define AL_ECHO_MAX_LRDELAY (0.404f)
#define AL_ECHO_DEFAULT_LRDELAY (0.1f)
#define AL_ECHO_MIN_DAMPING (0.0f)
#define AL_ECHO_MAX_DAMPING (0.99f)
#define AL_ECHO_DEFAULT_DAMPING (0.5f)
#define AL_ECHO_MIN_FEEDBACK (0.0f)
#define AL_ECHO_MAX_FEEDBACK (1.0f)
#define AL_ECHO_DEFAULT_FEEDBACK (0.5f)
#define AL_ECHO_MIN_SPREAD (-1.0f)
#define AL_ECHO_MAX_SPREAD (1.0f)
#define AL_ECHO_DEFAULT_SPREAD (-1.0f)
/* Flanger effect */
#define AL_FLANGER_WAVEFORM_SINUSOID (0)
#define AL_FLANGER_WAVEFORM_TRIANGLE (1)
#define AL_FLANGER_MIN_WAVEFORM (0)
#define AL_FLANGER_MAX_WAVEFORM (1)
#define AL_FLANGER_DEFAULT_WAVEFORM (1)
#define AL_FLANGER_MIN_PHASE (-180)
#define AL_FLANGER_MAX_PHASE (180)
#define AL_FLANGER_DEFAULT_PHASE (0)
#define AL_FLANGER_MIN_RATE (0.0f)
#define AL_FLANGER_MAX_RATE (10.0f)
#define AL_FLANGER_DEFAULT_RATE (0.27f)
#define AL_FLANGER_MIN_DEPTH (0.0f)
#define AL_FLANGER_MAX_DEPTH (1.0f)
#define AL_FLANGER_DEFAULT_DEPTH (1.0f)
#define AL_FLANGER_MIN_FEEDBACK (-1.0f)
#define AL_FLANGER_MAX_FEEDBACK (1.0f)
#define AL_FLANGER_DEFAULT_FEEDBACK (-0.5f)
#define AL_FLANGER_MIN_DELAY (0.0f)
#define AL_FLANGER_MAX_DELAY (0.004f)
#define AL_FLANGER_DEFAULT_DELAY (0.002f)
/* Frequency shifter effect */
#define AL_FREQUENCY_SHIFTER_MIN_FREQUENCY (0.0f)
#define AL_FREQUENCY_SHIFTER_MAX_FREQUENCY (24000.0f)
#define AL_FREQUENCY_SHIFTER_DEFAULT_FREQUENCY (0.0f)
#define AL_FREQUENCY_SHIFTER_MIN_LEFT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_MAX_LEFT_DIRECTION (2)
#define AL_FREQUENCY_SHIFTER_DEFAULT_LEFT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_DIRECTION_DOWN (0)
#define AL_FREQUENCY_SHIFTER_DIRECTION_UP (1)
#define AL_FREQUENCY_SHIFTER_DIRECTION_OFF (2)
#define AL_FREQUENCY_SHIFTER_MIN_RIGHT_DIRECTION (0)
#define AL_FREQUENCY_SHIFTER_MAX_RIGHT_DIRECTION (2)
#define AL_FREQUENCY_SHIFTER_DEFAULT_RIGHT_DIRECTION (0)
/* Vocal morpher effect */
#define AL_VOCAL_MORPHER_MIN_PHONEMEA (0)
#define AL_VOCAL_MORPHER_MAX_PHONEMEA (29)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA (0)
#define AL_VOCAL_MORPHER_MIN_PHONEMEA_COARSE_TUNING (-24)
#define AL_VOCAL_MORPHER_MAX_PHONEMEA_COARSE_TUNING (24)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEA_COARSE_TUNING (0)
#define AL_VOCAL_MORPHER_MIN_PHONEMEB (0)
#define AL_VOCAL_MORPHER_MAX_PHONEMEB (29)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB (10)
#define AL_VOCAL_MORPHER_MIN_PHONEMEB_COARSE_TUNING (-24)
#define AL_VOCAL_MORPHER_MAX_PHONEMEB_COARSE_TUNING (24)
#define AL_VOCAL_MORPHER_DEFAULT_PHONEMEB_COARSE_TUNING (0)
#define AL_VOCAL_MORPHER_PHONEME_A (0)
#define AL_VOCAL_MORPHER_PHONEME_E (1)
#define AL_VOCAL_MORPHER_PHONEME_I (2)
#define AL_VOCAL_MORPHER_PHONEME_O (3)
#define AL_VOCAL_MORPHER_PHONEME_U (4)
#define AL_VOCAL_MORPHER_PHONEME_AA (5)
#define AL_VOCAL_MORPHER_PHONEME_AE (6)
#define AL_VOCAL_MORPHER_PHONEME_AH (7)
#define AL_VOCAL_MORPHER_PHONEME_AO (8)
#define AL_VOCAL_MORPHER_PHONEME_EH (9)
#define AL_VOCAL_MORPHER_PHONEME_ER (10)
#define AL_VOCAL_MORPHER_PHONEME_IH (11)
#define AL_VOCAL_MORPHER_PHONEME_IY (12)
#define AL_VOCAL_MORPHER_PHONEME_UH (13)
#define AL_VOCAL_MORPHER_PHONEME_UW (14)
#define AL_VOCAL_MORPHER_PHONEME_B (15)
#define AL_VOCAL_MORPHER_PHONEME_D (16)
#define AL_VOCAL_MORPHER_PHONEME_F (17)
#define AL_VOCAL_MORPHER_PHONEME_G (18)
#define AL_VOCAL_MORPHER_PHONEME_J (19)
#define AL_VOCAL_MORPHER_PHONEME_K (20)
#define AL_VOCAL_MORPHER_PHONEME_L (21)
#define AL_VOCAL_MORPHER_PHONEME_M (22)
#define AL_VOCAL_MORPHER_PHONEME_N (23)
#define AL_VOCAL_MORPHER_PHONEME_P (24)
#define AL_VOCAL_MORPHER_PHONEME_R (25)
#define AL_VOCAL_MORPHER_PHONEME_S (26)
#define AL_VOCAL_MORPHER_PHONEME_T (27)
#define AL_VOCAL_MORPHER_PHONEME_V (28)
#define AL_VOCAL_MORPHER_PHONEME_Z (29)
#define AL_VOCAL_MORPHER_WAVEFORM_SINUSOID (0)
#define AL_VOCAL_MORPHER_WAVEFORM_TRIANGLE (1)
#define AL_VOCAL_MORPHER_WAVEFORM_SAWTOOTH (2)
#define AL_VOCAL_MORPHER_MIN_WAVEFORM (0)
#define AL_VOCAL_MORPHER_MAX_WAVEFORM (2)
#define AL_VOCAL_MORPHER_DEFAULT_WAVEFORM (0)
#define AL_VOCAL_MORPHER_MIN_RATE (0.0f)
#define AL_VOCAL_MORPHER_MAX_RATE (10.0f)
#define AL_VOCAL_MORPHER_DEFAULT_RATE (1.41f)
/* Pitch shifter effect */
#define AL_PITCH_SHIFTER_MIN_COARSE_TUNE (-12)
#define AL_PITCH_SHIFTER_MAX_COARSE_TUNE (12)
#define AL_PITCH_SHIFTER_DEFAULT_COARSE_TUNE (12)
#define AL_PITCH_SHIFTER_MIN_FINE_TUNE (-50)
#define AL_PITCH_SHIFTER_MAX_FINE_TUNE (50)
#define AL_PITCH_SHIFTER_DEFAULT_FINE_TUNE (0)
/* Ring modulator effect */
#define AL_RING_MODULATOR_MIN_FREQUENCY (0.0f)
#define AL_RING_MODULATOR_MAX_FREQUENCY (8000.0f)
#define AL_RING_MODULATOR_DEFAULT_FREQUENCY (440.0f)
#define AL_RING_MODULATOR_MIN_HIGHPASS_CUTOFF (0.0f)
#define AL_RING_MODULATOR_MAX_HIGHPASS_CUTOFF (24000.0f)
#define AL_RING_MODULATOR_DEFAULT_HIGHPASS_CUTOFF (800.0f)
#define AL_RING_MODULATOR_SINUSOID (0)
#define AL_RING_MODULATOR_SAWTOOTH (1)
#define AL_RING_MODULATOR_SQUARE (2)
#define AL_RING_MODULATOR_MIN_WAVEFORM (0)
#define AL_RING_MODULATOR_MAX_WAVEFORM (2)
#define AL_RING_MODULATOR_DEFAULT_WAVEFORM (0)
/* Autowah effect */
#define AL_AUTOWAH_MIN_ATTACK_TIME (0.0001f)
#define AL_AUTOWAH_MAX_ATTACK_TIME (1.0f)
#define AL_AUTOWAH_DEFAULT_ATTACK_TIME (0.06f)
#define AL_AUTOWAH_MIN_RELEASE_TIME (0.0001f)
#define AL_AUTOWAH_MAX_RELEASE_TIME (1.0f)
#define AL_AUTOWAH_DEFAULT_RELEASE_TIME (0.06f)
#define AL_AUTOWAH_MIN_RESONANCE (2.0f)
#define AL_AUTOWAH_MAX_RESONANCE (1000.0f)
#define AL_AUTOWAH_DEFAULT_RESONANCE (1000.0f)
#define AL_AUTOWAH_MIN_PEAK_GAIN (0.00003f)
#define AL_AUTOWAH_MAX_PEAK_GAIN (31621.0f)
#define AL_AUTOWAH_DEFAULT_PEAK_GAIN (11.22f)
/* Compressor effect */
#define AL_COMPRESSOR_MIN_ONOFF (0)
#define AL_COMPRESSOR_MAX_ONOFF (1)
#define AL_COMPRESSOR_DEFAULT_ONOFF (1)
/* Equalizer effect */
#define AL_EQUALIZER_MIN_LOW_GAIN (0.126f)
#define AL_EQUALIZER_MAX_LOW_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_LOW_GAIN (1.0f)
#define AL_EQUALIZER_MIN_LOW_CUTOFF (50.0f)
#define AL_EQUALIZER_MAX_LOW_CUTOFF (800.0f)
#define AL_EQUALIZER_DEFAULT_LOW_CUTOFF (200.0f)
#define AL_EQUALIZER_MIN_MID1_GAIN (0.126f)
#define AL_EQUALIZER_MAX_MID1_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_MID1_GAIN (1.0f)
#define AL_EQUALIZER_MIN_MID1_CENTER (200.0f)
#define AL_EQUALIZER_MAX_MID1_CENTER (3000.0f)
#define AL_EQUALIZER_DEFAULT_MID1_CENTER (500.0f)
#define AL_EQUALIZER_MIN_MID1_WIDTH (0.01f)
#define AL_EQUALIZER_MAX_MID1_WIDTH (1.0f)
#define AL_EQUALIZER_DEFAULT_MID1_WIDTH (1.0f)
#define AL_EQUALIZER_MIN_MID2_GAIN (0.126f)
#define AL_EQUALIZER_MAX_MID2_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_MID2_GAIN (1.0f)
#define AL_EQUALIZER_MIN_MID2_CENTER (1000.0f)
#define AL_EQUALIZER_MAX_MID2_CENTER (8000.0f)
#define AL_EQUALIZER_DEFAULT_MID2_CENTER (3000.0f)
#define AL_EQUALIZER_MIN_MID2_WIDTH (0.01f)
#define AL_EQUALIZER_MAX_MID2_WIDTH (1.0f)
#define AL_EQUALIZER_DEFAULT_MID2_WIDTH (1.0f)
#define AL_EQUALIZER_MIN_HIGH_GAIN (0.126f)
#define AL_EQUALIZER_MAX_HIGH_GAIN (7.943f)
#define AL_EQUALIZER_DEFAULT_HIGH_GAIN (1.0f)
#define AL_EQUALIZER_MIN_HIGH_CUTOFF (4000.0f)
#define AL_EQUALIZER_MAX_HIGH_CUTOFF (16000.0f)
#define AL_EQUALIZER_DEFAULT_HIGH_CUTOFF (6000.0f)
/* Source parameter value ranges and defaults. */
#define AL_MIN_AIR_ABSORPTION_FACTOR (0.0f)
#define AL_MAX_AIR_ABSORPTION_FACTOR (10.0f)
#define AL_DEFAULT_AIR_ABSORPTION_FACTOR (0.0f)
#define AL_MIN_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_MAX_ROOM_ROLLOFF_FACTOR (10.0f)
#define AL_DEFAULT_ROOM_ROLLOFF_FACTOR (0.0f)
#define AL_MIN_CONE_OUTER_GAINHF (0.0f)
#define AL_MAX_CONE_OUTER_GAINHF (1.0f)
#define AL_DEFAULT_CONE_OUTER_GAINHF (1.0f)
#define AL_MIN_DIRECT_FILTER_GAINHF_AUTO AL_FALSE
#define AL_MAX_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
#define AL_DEFAULT_DIRECT_FILTER_GAINHF_AUTO AL_TRUE
#define AL_MIN_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_FALSE
#define AL_MAX_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAIN_AUTO AL_TRUE
#define AL_MIN_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_FALSE
#define AL_MAX_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
#define AL_DEFAULT_AUXILIARY_SEND_FILTER_GAINHF_AUTO AL_TRUE
/* Listener parameter value ranges and defaults. */
#define AL_MIN_METERS_PER_UNIT FLT_MIN
#define AL_MAX_METERS_PER_UNIT FLT_MAX
#define AL_DEFAULT_METERS_PER_UNIT (1.0f)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* AL_EFX_H */

110
jni/OpenAL/include/config.h Executable file
View File

@ -0,0 +1,110 @@
#ifndef CONFIG_H
#define CONFIG_H
/* Define to the library version */
#define ALSOFT_VERSION "1.12.854"
/* Define if we have the Android backend */
#if defined(ANDROID)
#if defined(POST_FROYO)
#define HAVE_OPENSLES 1
#endif
#define HAVE_AUDIOTRACK 1
// For throttling AlSource.c
#define MAX_SOURCES_LOW 8
#define MAX_SOURCES_HIGH 64
#endif
/* Define if we have the ALSA backend */
/* #cmakedefine HAVE_ALSA */
/* Define if we have the OSS backend */
/* #cmakedefine HAVE_OSS */
/* Define if we have the Solaris backend */
/* #cmakedefine HAVE_SOLARIS */
/* Define if we have the DSound backend */
/* #cmakedefine HAVE_DSOUND */
/* Define if we have the Wave Writer backend */
/* #cmakedefine HAVE_WAVE */
/* Define if we have the Windows Multimedia backend */
/* #cmakedefine HAVE_WINMM */
/* Define if we have the PortAudio backend */
/* #cmakedefine HAVE_PORTAUDIO */
/* Define if we have the PulseAudio backend */
/* #cmakedefine HAVE_PULSEAUDIO */
/* Define if we have dlfcn.h */
#define HAVE_DLFCN_H 1
/* 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 acosf function */
#define HAVE_ACOSF 1
/* Define if we have the atanf function */
#define HAVE_ATANF 1
/* Define if we have the fabsf function */
#define HAVE_FABSF 1
/* Define if we have the strtof function */
#define HAVE_STRTOF 1
/* Define if we have stdint.h */
#define HAVE_STDINT_H 1
/* Define if we have the __int64 type */
/* #cmakedefine HAVE___INT64 */
/* Define to the size of a long int type */
#define SIZEOF_LONG 4
/* Define to the size of a long long int type */
#define SIZEOF_LONG_LONG 8
/* Define to the size of an unsigned int type */
#define SIZEOF_UINT 4
/* Define to the size of a void pointer type */
#define SIZEOF_VOIDP 4
/* Define if we have GCC's destructor attribute */
#define HAVE_GCC_DESTRUCTOR 1
/* Define if we have GCC's format attribute */
#define HAVE_GCC_FORMAT 1
/* Define if we have pthread_np.h */
/* #cmakedefine HAVE_PTHREAD_NP_H */
/* Define if we have float.h */
/* #cmakedefine HAVE_FLOAT_H */
/* Define if we have fenv.h */
#define HAVE_FENV_H 1
/* Define if we have fesetround() */
/* #cmakedefine HAVE_FESETROUND */
/* Define if we have _controlfp() */
/* #cmakedefine HAVE__CONTROLFP */
/* Define if we have pthread_setschedparam() */
#define HAVE_PTHREAD_SETSCHEDPARAM 1
#endif

View File

BIN
libs/armeabi/libopenal.so Executable file

Binary file not shown.

10
local.properties Normal file
View File

@ -0,0 +1,10 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must *NOT* be checked in Version Control Systems,
# as it contains information specific to your local configuration.
# location of the SDK. This is only used by Ant
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=/Developer/AndroidSDK

40
proguard.cfg Normal file
View File

@ -0,0 +1,40 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

BIN
res/drawable-hdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
res/drawable-ldpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
res/drawable-mdpi/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

13
res/layout/main.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, openal_soft"
/>
</LinearLayout>

4
res/values/strings.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">openal_soft</string>
</resources>

View File

@ -0,0 +1,15 @@
package com.apportable.openal_soft;
import android.app.Activity;
import android.os.Bundle;
public class openal_soft extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}