Compare commits
320 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd83e006ec | |||
| e51574c764 | |||
| 893a1bedbc | |||
| 4621a7b426 | |||
| 4808313e70 | |||
| 1fb9311d82 | |||
| dd34daed42 | |||
| 830428fb06 | |||
| 0ca7ab2cf8 | |||
| a0c39989f5 | |||
| 209d09ae13 | |||
| 0c030f7d9c | |||
| 2d800e99e2 | |||
| 0518ecca14 | |||
| 43b9027611 | |||
| 40ea4f4b46 | |||
| 4f624cb734 | |||
| b03013d6a7 | |||
| 9e79d144de | |||
| 40b3f60cde | |||
| 2b27d243ca | |||
| 2f07c46e20 | |||
| 3da1b540fd | |||
| 92dde81296 | |||
| e2368eb960 | |||
| 3e71a7cb94 | |||
| b92ad830ef | |||
| fc7adccd6f | |||
| 97bf718d0e | |||
| eb6360e1f8 | |||
| 41b1ba146a | |||
| 6450d0cbca | |||
| 4e281350a0 | |||
| e868dad61c | |||
| 4a3d36a176 | |||
| f3dddb6e63 | |||
| 3c3e3b123b | |||
| f02a9935c6 | |||
| 3711735ed9 | |||
| 2c802cc10a | |||
| e2e502970c | |||
| 404d601666 | |||
| 252fc40f78 | |||
| fb21a73b4e | |||
| 138a4c6d92 | |||
| c802bfccef | |||
| fae4959db3 | |||
| 8a67e5cfa2 | |||
| 617def3ef0 | |||
| 4f5aafe59f | |||
| a14383d6cc | |||
| fe1903fb56 | |||
| f0d27e5f91 | |||
| a852669dce | |||
| 3240894cd5 | |||
| 0b679167c9 | |||
| 5ac0a93fba | |||
| f7655d44a2 | |||
| 38e6bfb702 | |||
| 20ede6de59 | |||
| 5c70e6b9ab | |||
| 9bd3b88a58 | |||
| e60281c927 | |||
| 01136ecd51 | |||
| 1212523470 | |||
| 73105b2d4b | |||
| 06ab9cf70e | |||
| a3d4868ef4 | |||
| 815b03855b | |||
| 6750bbb1d7 | |||
| 43c8c4fa29 | |||
| 25b8a95987 | |||
| 99fcd6f816 | |||
| 513c6db0d5 | |||
| 1b7f01b7cc | |||
| a4f21aaa64 | |||
| 39bc2ba65c | |||
| d598f82722 | |||
| c22408cb2a | |||
| 8c3419ed48 | |||
| a98361ebbe | |||
| 999f0783c5 | |||
| 2a6dd2f243 | |||
| f3349221c6 | |||
| 65c7c468cc | |||
| ebdf636759 | |||
| 6b870714a9 | |||
| 708f3ccc3d | |||
| 84f4afa5f2 | |||
| 991e21a712 | |||
| 1a9cf7ab80 | |||
| 9501f1cb9e | |||
| d52cb3708b | |||
| fa8d374613 | |||
| 0d26b0dcc2 | |||
| a6287fd407 | |||
| 16bdf79d4c | |||
| 0b47844606 | |||
| 468759e6ab | |||
| f138774d78 | |||
| 068da3fe83 | |||
| 29b11db13f | |||
| dca6254b35 | |||
| cccec40e87 | |||
| b5d9d8e005 | |||
| 825c5b5282 | |||
| 25ca179389 | |||
| 8bd0592e3f | |||
| 06a0d1b86e | |||
| 41b2c2f3bb | |||
| 68faef5b84 | |||
| abf1309fb6 | |||
| d3891af36e | |||
| ed82194260 | |||
| 012e61b105 | |||
| d19d7321d9 | |||
| d4e82d441e | |||
| 2ceea21f76 | |||
| 12327da4fe | |||
| 52d403b0d1 | |||
| ccd35bffe7 | |||
| d1c93525ed | |||
| f0732426f2 | |||
| eedbd1e81c | |||
| 6005e7f27f | |||
| e779e64c95 | |||
| 3baaf99a6e | |||
| 4a86983a6f | |||
| c19d9d3452 | |||
| 79b6d89b3f | |||
| 535e8fd0f7 | |||
| a240abb6c8 | |||
| dd9d30e248 | |||
| 95535ce99e | |||
| df2e82da78 | |||
| a1daec66e2 | |||
| 657ee85136 | |||
| 965306b296 | |||
| 28086f6cb7 | |||
| 45bb010b28 | |||
| 90e0c74721 | |||
| a20341ac2a | |||
| 7635afcb52 | |||
| 74aee374a6 | |||
| 4f70766b95 | |||
| 9f58edd7a8 | |||
| 0f3a575a09 | |||
| ec74fb9ba2 | |||
| ff809f2271 | |||
| 41f52fdd6a | |||
| aa827790bd | |||
| 38e7bd5359 | |||
| 613ce3f976 | |||
| ce8a0a9fd5 | |||
| f59e4ba7c2 | |||
| df469bfdea | |||
| f4642953d4 | |||
| 88b0c30152 | |||
| 01183ad93b | |||
| 3f97af4c8c | |||
| 4c5cb2189b | |||
| 98ff6f990a | |||
| aaa81e00b7 | |||
| 1c44a96768 | |||
| 34fef456c8 | |||
| 7e81918f7b | |||
| 1b840a3db8 | |||
| 4e440fff62 | |||
| 81208acd6e | |||
| af3b5c23c8 | |||
| 9f208417df | |||
| f1ce139997 | |||
| f56dddfa73 | |||
| 2bf1979d4a | |||
| 89cab3cd39 | |||
| 6723d27e06 | |||
| 1c03025090 | |||
| 7a37a63b8e | |||
| 2b5fdad2c8 | |||
| a6f9ede849 | |||
| 78dac1bf4a | |||
| 795909c39e | |||
| 3c042a054d | |||
| 332d66c183 | |||
| de006947ac | |||
| 8a128e5d25 | |||
| 34cbacf424 | |||
| f2fa5e7c88 | |||
| 3b735cc34a | |||
| 238caa1492 | |||
| e5ebe345ad | |||
| 965608356f | |||
| bc1ce7b3ac | |||
| 6a3619c40f | |||
| 50fa9a44be | |||
| 4937a48bd9 | |||
| 987a81c4de | |||
| f5e0500df4 | |||
| 37924887e8 | |||
| 0db7c4131b | |||
| a56a974149 | |||
| af7f3768fa | |||
| 0865db564f | |||
| 2b020040b4 | |||
| 3ae5fcbd7e | |||
| ac4fc4026c | |||
| 9737f68315 | |||
| 2a8c26e390 | |||
| 3c395a82db | |||
| 15c6b9b165 | |||
| 147fd9de4e | |||
| 0bca771a88 | |||
| f4ff63e271 | |||
| bbcf4e8c1d | |||
| 2859357939 | |||
| 2cbb565d09 | |||
| 4d157d2849 | |||
| 64cd763e19 | |||
| c3f387da70 | |||
| 6ebeb3b4f7 | |||
| 2e18baa3c8 | |||
| c9e87a19a9 | |||
| 3b87e29e63 | |||
| e9a20cb985 | |||
| cfc5205569 | |||
| 17dfaa3aae | |||
| 0a3eba08d8 | |||
| add53e28c2 | |||
| f42f655ea9 | |||
| 8304fc1bef | |||
| ea84fee952 | |||
| d6fd52a0e5 | |||
| 0dde7dd88a | |||
| 1323e11701 | |||
| 7ac9944bb3 | |||
| e32e2fd6b8 | |||
| 6bd535bed0 | |||
| 524c88c402 | |||
| 1c096b101d | |||
| 583dc8dbca | |||
| befa4e7528 | |||
| bc6751237c | |||
| 6f3be31b60 | |||
| 8001d86751 | |||
| acca3e5a21 | |||
| d17f835e74 | |||
| ef1f8aa9a0 | |||
| a5ac6eb524 | |||
| ac84d95c6e | |||
| 785f52aa29 | |||
| 051195a991 | |||
| 90ca6675c2 | |||
| 0db9730a50 | |||
| ad2643d8af | |||
| 46840ee787 | |||
| 1e0282a238 | |||
| 259e4f5b38 | |||
| e44229c74e | |||
| 92827cc467 | |||
| dd3d5bc2d4 | |||
| b4c7b3309a | |||
| 010a66487d | |||
| aed35fd811 | |||
| 8d9838012d | |||
| 57d36ec582 | |||
| febc2a50cb | |||
| 74e128bd0f | |||
| c34d78f417 | |||
| 611bd0b2d3 | |||
| 267d38cf20 | |||
| 26456f13e1 | |||
| 2484c44db0 | |||
| a8a13fcbd8 | |||
| 0a193c5645 | |||
| 2450ee1723 | |||
| 67f1cdfcbe | |||
| 549d542a31 | |||
| 2cdb58fb85 | |||
| 68ab232364 | |||
| 871d61f3f9 | |||
| b08bd3746e | |||
| 39ab0b0aa3 | |||
| 5c70cacc13 | |||
| 8c2cd057b2 | |||
| fdc4133ac9 | |||
| 3833c021c0 | |||
| cafbd9461e | |||
| 6995ac1ed2 | |||
| 58e3dc3d52 | |||
| 3e49e79140 | |||
| dec8e81211 | |||
| 4188a5f3f3 | |||
| 31d124582b | |||
| 248e079301 | |||
| 5ce850570f | |||
| 648464a2da | |||
| 29f77003c0 | |||
| dfa38ed7a5 | |||
| 66c918c84b | |||
| 77f55da6c7 | |||
| d6af7cdcb2 | |||
| 0ad8047820 | |||
| 2115f578e9 | |||
| 511b4790d0 | |||
| d6491e21f9 | |||
| cff0f938e5 | |||
| 5418519637 | |||
| b023dbe7b8 | |||
| 8092cd9205 | |||
| 60da5bd338 | |||
| c9e64596a4 | |||
| 08bd5e8b37 | |||
| 125b743e5c | |||
| 9a3eb397f4 | |||
| 84c1f2bfd0 | |||
| d7ba49ea62 | |||
| e47557630e | |||
| f6a1e53f19 | |||
| a0a015f19f | |||
| e3bea63f94 |
@@ -1 +1,5 @@
|
||||
build
|
||||
winbuild
|
||||
include/sndio.h
|
||||
include/sys
|
||||
openal-soft.kdev4
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef __MINGW64__
|
||||
#ifdef __MINGW32__
|
||||
#define _WIN32_IE 0x501
|
||||
#else
|
||||
#define _WIN32_IE 0x400
|
||||
|
||||
+9
-20
@@ -33,7 +33,7 @@ typedef struct ALdedicatedState {
|
||||
// Must be first in all effects!
|
||||
ALeffectState state;
|
||||
|
||||
ALfloat gains[MAXCHANNELS];
|
||||
ALfloat gains[MaxChannels];
|
||||
} ALdedicatedState;
|
||||
|
||||
|
||||
@@ -53,40 +53,29 @@ static ALboolean DedicatedDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
static ALvoid DedicatedUpdate(ALeffectState *effect, ALCdevice *device, const ALeffectslot *Slot)
|
||||
{
|
||||
ALdedicatedState *state = (ALdedicatedState*)effect;
|
||||
const ALfloat *ChannelGain;
|
||||
ALfloat Gain;
|
||||
ALint pos;
|
||||
ALsizei s;
|
||||
|
||||
Gain = Slot->Gain * Slot->effect.Dedicated.Gain;
|
||||
for(s = 0;s < MAXCHANNELS;s++)
|
||||
for(s = 0;s < MaxChannels;s++)
|
||||
state->gains[s] = 0.0f;
|
||||
|
||||
if(Slot->effect.type == AL_EFFECT_DEDICATED_DIALOGUE)
|
||||
{
|
||||
pos = aluCart2LUTpos(1.0f, 0.0f);
|
||||
ChannelGain = device->PanningLUT[pos];
|
||||
|
||||
for(s = 0;s < MAXCHANNELS;s++)
|
||||
state->gains[s] = ChannelGain[s] * Gain;
|
||||
}
|
||||
ComputeAngleGains(device, atan2f(0.0f, 1.0f), 0.0f, Gain, state->gains);
|
||||
else if(Slot->effect.type == AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT)
|
||||
state->gains[LFE] = Gain;
|
||||
}
|
||||
|
||||
static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid DedicatedProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALdedicatedState *state = (ALdedicatedState*)effect;
|
||||
const ALfloat *gains = state->gains;
|
||||
ALuint i, s;
|
||||
ALuint i, c;
|
||||
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
ALfloat sample;
|
||||
|
||||
sample = SamplesIn[i];
|
||||
for(s = 0;s < MAXCHANNELS;s++)
|
||||
SamplesOut[i][s] = sample * gains[s];
|
||||
for(i = 0;i < SamplesToDo;i++)
|
||||
SamplesOut[c][i] = SamplesIn[i] * gains[c];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +93,7 @@ ALeffectState *DedicatedCreate(void)
|
||||
state->state.Update = DedicatedUpdate;
|
||||
state->state.Process = DedicatedProcess;
|
||||
|
||||
for(s = 0;s < MAXCHANNELS;s++)
|
||||
for(s = 0;s < MaxChannels;s++)
|
||||
state->gains[s] = 0.0f;
|
||||
|
||||
return &state->state;
|
||||
|
||||
+13
-29
@@ -44,7 +44,7 @@ typedef struct ALechoState {
|
||||
} Tap[2];
|
||||
ALuint Offset;
|
||||
/* The panning gains for the two taps */
|
||||
ALfloat Gain[2][MAXCHANNELS];
|
||||
ALfloat Gain[2][MaxChannels];
|
||||
|
||||
ALfloat FeedGain;
|
||||
|
||||
@@ -94,10 +94,9 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
ALuint frequency = Device->Frequency;
|
||||
ALfloat dirGain, ambientGain;
|
||||
const ALfloat *ChannelGain;
|
||||
ALfloat lrpan, cw, g, gain;
|
||||
ALuint i, pos;
|
||||
ALfloat dirGain;
|
||||
ALuint i;
|
||||
|
||||
state->Tap[0].delay = fastf2u(Slot->effect.Echo.Delay * frequency) + 1;
|
||||
state->Tap[1].delay = fastf2u(Slot->effect.Echo.LRDelay * frequency);
|
||||
@@ -107,42 +106,27 @@ static ALvoid EchoUpdate(ALeffectState *effect, ALCdevice *Device, const ALeffec
|
||||
|
||||
state->FeedGain = Slot->effect.Echo.Feedback;
|
||||
|
||||
cw = aluCos(F_PI*2.0f * LOWPASSFREQREF / frequency);
|
||||
cw = cosf(F_PI*2.0f * LOWPASSFREQREF / frequency);
|
||||
g = 1.0f - Slot->effect.Echo.Damping;
|
||||
state->iirFilter.coeff = lpCoeffCalc(g, cw);
|
||||
|
||||
gain = Slot->Gain;
|
||||
for(i = 0;i < MAXCHANNELS;i++)
|
||||
for(i = 0;i < MaxChannels;i++)
|
||||
{
|
||||
state->Gain[0][i] = 0.0f;
|
||||
state->Gain[1][i] = 0.0f;
|
||||
}
|
||||
|
||||
ambientGain = aluSqrt(1.0f/Device->NumChan);
|
||||
dirGain = aluFabs(lrpan);
|
||||
dirGain = fabsf(lrpan);
|
||||
|
||||
/* First tap panning */
|
||||
pos = aluCart2LUTpos(0.0f, ((lrpan>0.0f)?-1.0f:1.0f));
|
||||
ChannelGain = Device->PanningLUT[pos];
|
||||
|
||||
for(i = 0;i < Device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = Device->Speaker2Chan[i];
|
||||
state->Gain[0][chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * gain;
|
||||
}
|
||||
ComputeAngleGains(Device, atan2f(-lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[0]);
|
||||
|
||||
/* Second tap panning */
|
||||
pos = aluCart2LUTpos(0.0f, ((lrpan>0.0f)?1.0f:-1.0f));
|
||||
ChannelGain = Device->PanningLUT[pos];
|
||||
|
||||
for(i = 0;i < Device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = Device->Speaker2Chan[i];
|
||||
state->Gain[1][chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * gain;
|
||||
}
|
||||
ComputeAngleGains(Device, atan2f(+lrpan, 0.0f), (1.0f-dirGain)*F_PI, gain, state->Gain[1]);
|
||||
}
|
||||
|
||||
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALechoState *state = (ALechoState*)effect;
|
||||
const ALuint mask = state->BufferLength-1;
|
||||
@@ -156,13 +140,13 @@ static ALvoid EchoProcess(ALeffectState *effect, ALuint SamplesToDo, const ALflo
|
||||
{
|
||||
/* First tap */
|
||||
smp = state->SampleBuffer[(offset-tap1) & mask];
|
||||
for(k = 0;k < MAXCHANNELS;k++)
|
||||
SamplesOut[i][k] += smp * state->Gain[0][k];
|
||||
for(k = 0;k < MaxChannels;k++)
|
||||
SamplesOut[k][i] += smp * state->Gain[0][k];
|
||||
|
||||
/* Second tap */
|
||||
smp = state->SampleBuffer[(offset-tap2) & mask];
|
||||
for(k = 0;k < MAXCHANNELS;k++)
|
||||
SamplesOut[i][k] += smp * state->Gain[1][k];
|
||||
for(k = 0;k < MaxChannels;k++)
|
||||
SamplesOut[k][i] += smp * state->Gain[1][k];
|
||||
|
||||
// Apply damping and feedback gain to the second tap, and mix in the
|
||||
// new sample
|
||||
|
||||
+12
-11
@@ -43,7 +43,7 @@ typedef struct ALmodulatorState {
|
||||
ALuint index;
|
||||
ALuint step;
|
||||
|
||||
ALfloat Gain[MAXCHANNELS];
|
||||
ALfloat Gain[MaxChannels];
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[1];
|
||||
@@ -55,7 +55,7 @@ typedef struct ALmodulatorState {
|
||||
|
||||
static __inline ALfloat Sin(ALuint index)
|
||||
{
|
||||
return aluSin(index * (F_PI*2.0f / WAVEFORM_FRACONE));
|
||||
return sinf(index * (F_PI*2.0f / WAVEFORM_FRACONE));
|
||||
}
|
||||
|
||||
static __inline ALfloat Saw(ALuint index)
|
||||
@@ -84,7 +84,8 @@ static __inline ALfloat hpFilter1P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
|
||||
#define DECL_TEMPLATE(func) \
|
||||
static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
|
||||
const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]) \
|
||||
const ALfloat *RESTRICT SamplesIn, \
|
||||
ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \
|
||||
{ \
|
||||
const ALuint step = state->step; \
|
||||
ALuint index = state->index; \
|
||||
@@ -101,8 +102,8 @@ static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
|
||||
\
|
||||
samp = hpFilter1P(&state->iirFilter, 0, samp); \
|
||||
\
|
||||
for(k = 0;k < MAXCHANNELS;k++) \
|
||||
SamplesOut[i][k] += state->Gain[k] * samp; \
|
||||
for(k = 0;k < MaxChannels;k++) \
|
||||
SamplesOut[k][i] += state->Gain[k] * samp; \
|
||||
} \
|
||||
state->index = index; \
|
||||
}
|
||||
@@ -144,14 +145,14 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL
|
||||
Device->Frequency);
|
||||
if(state->step == 0) state->step = 1;
|
||||
|
||||
cw = aluCos(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff /
|
||||
Device->Frequency);
|
||||
a = (2.0f-cw) - aluSqrt(aluPow(2.0f-cw, 2.0f) - 1.0f);
|
||||
cw = cosf(F_PI*2.0f * Slot->effect.Modulator.HighPassCutoff /
|
||||
Device->Frequency);
|
||||
a = (2.0f-cw) - sqrtf(powf(2.0f-cw, 2.0f) - 1.0f);
|
||||
state->iirFilter.coeff = a;
|
||||
|
||||
gain = aluSqrt(1.0f/Device->NumChan);
|
||||
gain = sqrtf(1.0f/Device->NumChan);
|
||||
gain *= Slot->Gain;
|
||||
for(index = 0;index < MAXCHANNELS;index++)
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
state->Gain[index] = 0.0f;
|
||||
for(index = 0;index < Device->NumChan;index++)
|
||||
{
|
||||
@@ -160,7 +161,7 @@ static ALvoid ModulatorUpdate(ALeffectState *effect, ALCdevice *Device, const AL
|
||||
}
|
||||
}
|
||||
|
||||
static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid ModulatorProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALmodulatorState *state = (ALmodulatorState*)effect;
|
||||
|
||||
|
||||
+85
-89
@@ -24,13 +24,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alEffect.h"
|
||||
#include "alFilter.h"
|
||||
#include "alError.h"
|
||||
#include "alu.h"
|
||||
|
||||
typedef struct DelayLine
|
||||
{
|
||||
@@ -85,7 +84,7 @@ typedef struct ALverbState {
|
||||
|
||||
// The gain for each output channel based on 3D panning (only for the
|
||||
// EAX path).
|
||||
ALfloat PanGain[MAXCHANNELS];
|
||||
ALfloat PanGain[MaxChannels];
|
||||
} Early;
|
||||
|
||||
// Decorrelator delay line.
|
||||
@@ -124,7 +123,7 @@ typedef struct ALverbState {
|
||||
|
||||
// The gain for each output channel based on 3D panning (only for the
|
||||
// EAX path).
|
||||
ALfloat PanGain[MAXCHANNELS];
|
||||
ALfloat PanGain[MaxChannels];
|
||||
} Late;
|
||||
|
||||
struct {
|
||||
@@ -157,6 +156,10 @@ typedef struct ALverbState {
|
||||
// The gain for each output channel (non-EAX path only; aliased from
|
||||
// Late.PanGain)
|
||||
ALfloat *Gain;
|
||||
|
||||
/* Temporary storage used when processing, before deinterlacing. */
|
||||
ALfloat ReverbSamples[BUFFERSIZE][4];
|
||||
ALfloat EarlySamples[BUFFERSIZE][4];
|
||||
} ALverbState;
|
||||
|
||||
/* This is a user config option for modifying the overall output of the reverb
|
||||
@@ -261,7 +264,7 @@ static __inline ALfloat EAXModulation(ALverbState *State, ALfloat in)
|
||||
// Calculate the sinus rythm (dependent on modulation time and the
|
||||
// sampling rate). The center of the sinus is moved to reduce the delay
|
||||
// of the effect when the time or depth are low.
|
||||
sinus = 1.0f - aluCos(F_PI*2.0f * State->Mod.Index / State->Mod.Range);
|
||||
sinus = 1.0f - cosf(F_PI*2.0f * State->Mod.Index / State->Mod.Range);
|
||||
|
||||
// The depth determines the range over which to read the input samples
|
||||
// from, so it must be filtered to reduce the distortion caused by even
|
||||
@@ -298,7 +301,7 @@ static __inline ALfloat EarlyDelayLineOut(ALverbState *State, ALuint index)
|
||||
|
||||
// Given an input sample, this function produces four-channel output for the
|
||||
// early reflections.
|
||||
static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *out)
|
||||
static __inline ALvoid EarlyReflection(ALverbState *State, ALfloat in, ALfloat *RESTRICT out)
|
||||
{
|
||||
ALfloat d[4], v, f[4];
|
||||
|
||||
@@ -369,7 +372,7 @@ static __inline ALfloat LateLowPassInOut(ALverbState *State, ALuint index, ALflo
|
||||
|
||||
// Given four decorrelated input samples, this function produces four-channel
|
||||
// output for the late reverb.
|
||||
static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out)
|
||||
static __inline ALvoid LateReverb(ALverbState *State, const ALfloat *RESTRICT in, ALfloat *RESTRICT out)
|
||||
{
|
||||
ALfloat d[4], f[4];
|
||||
|
||||
@@ -440,7 +443,7 @@ static __inline ALvoid LateReverb(ALverbState *State, ALfloat *in, ALfloat *out)
|
||||
|
||||
// Given an input sample, this function mixes echo into the four-channel late
|
||||
// reverb.
|
||||
static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late)
|
||||
static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *RESTRICT late)
|
||||
{
|
||||
ALfloat out, feed;
|
||||
|
||||
@@ -474,9 +477,9 @@ static __inline ALvoid EAXEcho(ALverbState *State, ALfloat in, ALfloat *late)
|
||||
|
||||
// Perform the non-EAX reverb pass on a given input sample, resulting in
|
||||
// four-channel output.
|
||||
static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
|
||||
static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *RESTRICT out)
|
||||
{
|
||||
ALfloat feed, taps[4];
|
||||
ALfloat feed, late[4], taps[4];
|
||||
|
||||
// Low-pass filter the incoming sample.
|
||||
in = lpFilter2P(&State->LpFilter, 0, in);
|
||||
@@ -486,7 +489,7 @@ static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early,
|
||||
|
||||
// Calculate the early reflection from the first delay tap.
|
||||
in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]);
|
||||
EarlyReflection(State, in, early);
|
||||
EarlyReflection(State, in, out);
|
||||
|
||||
// Feed the decorrelator from the energy-attenuated output of the second
|
||||
// delay tap.
|
||||
@@ -501,13 +504,19 @@ static __inline ALvoid VerbPass(ALverbState *State, ALfloat in, ALfloat *early,
|
||||
taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]);
|
||||
LateReverb(State, taps, late);
|
||||
|
||||
// Mix early reflections and late reverb.
|
||||
out[0] += late[0];
|
||||
out[1] += late[1];
|
||||
out[2] += late[2];
|
||||
out[3] += late[3];
|
||||
|
||||
// Step all delays forward one sample.
|
||||
State->Offset++;
|
||||
}
|
||||
|
||||
// Perform the EAX reverb pass on a given input sample, resulting in four-
|
||||
// channel output.
|
||||
static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *early, ALfloat *late)
|
||||
static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *RESTRICT early, ALfloat *RESTRICT late)
|
||||
{
|
||||
ALfloat feed, taps[4];
|
||||
|
||||
@@ -546,53 +555,62 @@ static __inline ALvoid EAXVerbPass(ALverbState *State, ALfloat in, ALfloat *earl
|
||||
|
||||
// This processes the reverb state, given the input samples and an output
|
||||
// buffer.
|
||||
static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid VerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
ALfloat (*RESTRICT out)[4] = State->ReverbSamples;
|
||||
ALuint index, c;
|
||||
ALfloat early[4], late[4], out[4];
|
||||
const ALfloat *panGain = State->Gain;
|
||||
|
||||
/* Process reverb for these samples. */
|
||||
for(index = 0;index < SamplesToDo;index++)
|
||||
VerbPass(State, SamplesIn[index], out[index]);
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
// Process reverb for this sample.
|
||||
VerbPass(State, SamplesIn[index], early, late);
|
||||
|
||||
// Mix early reflections and late reverb.
|
||||
out[0] = (early[0] + late[0]);
|
||||
out[1] = (early[1] + late[1]);
|
||||
out[2] = (early[2] + late[2]);
|
||||
out[3] = (early[3] + late[3]);
|
||||
|
||||
// Output the results.
|
||||
for(c = 0;c < MAXCHANNELS;c++)
|
||||
SamplesOut[index][c] += panGain[c] * out[c&3];
|
||||
ALfloat gain = State->Gain[c];
|
||||
if(gain > 0.00001f)
|
||||
{
|
||||
for(index = 0;index < SamplesToDo;index++)
|
||||
SamplesOut[c][index] += gain * out[index][c&3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This processes the EAX reverb state, given the input samples and an output
|
||||
// buffer.
|
||||
static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid EAXVerbProcess(ALeffectState *effect, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
ALverbState *State = (ALverbState*)effect;
|
||||
ALfloat (*RESTRICT early)[4] = State->EarlySamples;
|
||||
ALfloat (*RESTRICT late)[4] = State->ReverbSamples;
|
||||
ALuint index, c;
|
||||
ALfloat early[4], late[4];
|
||||
|
||||
/* Process reverb for these samples. */
|
||||
for(index = 0;index < SamplesToDo;index++)
|
||||
{
|
||||
// Process reverb for this sample.
|
||||
EAXVerbPass(State, SamplesIn[index], early, late);
|
||||
EAXVerbPass(State, SamplesIn[index], early[index], late[index]);
|
||||
|
||||
for(c = 0;c < MAXCHANNELS;c++)
|
||||
SamplesOut[index][c] += State->Early.PanGain[c]*early[c&3] +
|
||||
State->Late.PanGain[c]*late[c&3];
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
ALfloat earlyGain = State->Early.PanGain[c];
|
||||
ALfloat lateGain = State->Late.PanGain[c];
|
||||
|
||||
if(earlyGain > 0.00001f)
|
||||
{
|
||||
for(index = 0;index < SamplesToDo;index++)
|
||||
SamplesOut[c][index] += earlyGain*early[index][c&3];
|
||||
}
|
||||
if(lateGain > 0.00001f)
|
||||
{
|
||||
for(index = 0;index < SamplesToDo;index++)
|
||||
SamplesOut[c][index] += lateGain*late[index][c&3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Given the allocated sample buffer, this function updates each delay line
|
||||
// offset.
|
||||
static __inline ALvoid RealizeLineOffset(ALfloat * sampleBuffer, DelayLine *Delay)
|
||||
static __inline ALvoid RealizeLineOffset(ALfloat *sampleBuffer, DelayLine *Delay)
|
||||
{
|
||||
Delay->Line = &sampleBuffer[(ALintptrEXT)Delay->Line];
|
||||
}
|
||||
@@ -720,8 +738,8 @@ static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
// is calculated given the current sample rate. This ensures that the
|
||||
// resulting filter response over time is consistent across all sample
|
||||
// rates.
|
||||
State->Mod.Coeff = aluPow(MODULATION_FILTER_COEFF,
|
||||
MODULATION_FILTER_CONST / frequency);
|
||||
State->Mod.Coeff = powf(MODULATION_FILTER_COEFF,
|
||||
MODULATION_FILTER_CONST / frequency);
|
||||
|
||||
// The early reflection and late all-pass filter line lengths are static,
|
||||
// so their offsets only need to be calculated once.
|
||||
@@ -744,21 +762,21 @@ static ALboolean ReverbDeviceUpdate(ALeffectState *effect, ALCdevice *Device)
|
||||
// until the decay reaches -60 dB.
|
||||
static __inline ALfloat CalcDecayCoeff(ALfloat length, ALfloat decayTime)
|
||||
{
|
||||
return aluPow(0.001f/*-60 dB*/, length/decayTime);
|
||||
return powf(0.001f/*-60 dB*/, length/decayTime);
|
||||
}
|
||||
|
||||
// Calculate a decay length from a coefficient and the time until the decay
|
||||
// reaches -60 dB.
|
||||
static __inline ALfloat CalcDecayLength(ALfloat coeff, ALfloat decayTime)
|
||||
{
|
||||
return aluLog10(coeff) * decayTime / aluLog10(0.001f)/*-60 dB*/;
|
||||
return log10f(coeff) * decayTime / log10f(0.001f)/*-60 dB*/;
|
||||
}
|
||||
|
||||
// Calculate the high frequency parameter for the I3DL2 coefficient
|
||||
// calculation.
|
||||
static __inline ALfloat CalcI3DL2HFreq(ALfloat hfRef, ALuint frequency)
|
||||
{
|
||||
return aluCos(F_PI*2.0f * hfRef / frequency);
|
||||
return cosf(F_PI*2.0f * hfRef / frequency);
|
||||
}
|
||||
|
||||
// Calculate an attenuation to be applied to the input of any echo models to
|
||||
@@ -778,7 +796,7 @@ static __inline ALfloat CalcDensityGain(ALfloat a)
|
||||
* calculated by inverting the square root of this approximation,
|
||||
* yielding: 1 / sqrt(1 / (1 - a^2)), simplified to: sqrt(1 - a^2).
|
||||
*/
|
||||
return aluSqrt(1.0f - (a * a));
|
||||
return sqrtf(1.0f - (a * a));
|
||||
}
|
||||
|
||||
// Calculate the mixing matrix coefficients given a diffusion factor.
|
||||
@@ -787,13 +805,13 @@ static __inline ALvoid CalcMatrixCoeffs(ALfloat diffusion, ALfloat *x, ALfloat *
|
||||
ALfloat n, t;
|
||||
|
||||
// The matrix is of order 4, so n is sqrt (4 - 1).
|
||||
n = aluSqrt(3.0f);
|
||||
t = diffusion * aluAtan(n);
|
||||
n = sqrtf(3.0f);
|
||||
t = diffusion * atanf(n);
|
||||
|
||||
// Calculate the first mixing matrix coefficient.
|
||||
*x = aluCos(t);
|
||||
*x = cosf(t);
|
||||
// Calculate the second mixing matrix coefficient.
|
||||
*y = aluSin(t) / n;
|
||||
*y = sinf(t) / n;
|
||||
}
|
||||
|
||||
// Calculate the limited HF ratio for use with the late reverb low-pass
|
||||
@@ -913,7 +931,7 @@ static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALverbState
|
||||
*/
|
||||
for(index = 0;index < 3;index++)
|
||||
{
|
||||
length = (DECO_FRACTION * aluPow(DECO_MULTIPLIER, (ALfloat)index)) *
|
||||
length = (DECO_FRACTION * powf(DECO_MULTIPLIER, (ALfloat)index)) *
|
||||
LATE_LINE_LENGTH[0] * (1.0f + (density * LATE_LINE_MULTIPLIER));
|
||||
State->DecoTap[index] = fastf2u(length * frequency);
|
||||
}
|
||||
@@ -947,7 +965,7 @@ static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix
|
||||
decayTime));
|
||||
|
||||
// Calculate the all-pass feed-back and feed-forward coefficient.
|
||||
State->Late.ApFeedCoeff = 0.5f * aluPow(diffusion, 2.0f);
|
||||
State->Late.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f);
|
||||
|
||||
for(index = 0;index < 4;index++)
|
||||
{
|
||||
@@ -991,7 +1009,7 @@ static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoT
|
||||
State->Echo.DensityGain = CalcDensityGain(State->Echo.Coeff);
|
||||
|
||||
// Calculate the echo all-pass feed coefficient.
|
||||
State->Echo.ApFeedCoeff = 0.5f * aluPow(diffusion, 2.0f);
|
||||
State->Echo.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f);
|
||||
|
||||
// Calculate the echo all-pass attenuation coefficient.
|
||||
State->Echo.ApCoeff = CalcDecayCoeff(ECHO_ALLPASS_LENGTH, decayTime);
|
||||
@@ -1016,24 +1034,21 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
ReflectionsPan[2] };
|
||||
ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1],
|
||||
LateReverbPan[2] };
|
||||
const ALfloat *ChannelGain;
|
||||
ALfloat ambientGain;
|
||||
ALfloat dirGain;
|
||||
ALfloat length;
|
||||
ALuint index;
|
||||
ALint pos;
|
||||
|
||||
Gain *= ReverbBoost;
|
||||
|
||||
// Attenuate non-directional reverb according to the number of channels
|
||||
ambientGain = aluSqrt(2.0f/Device->NumChan);
|
||||
/* Attenuate reverb according to its coverage (dirGain=0 will give
|
||||
* Gain*ambientGain, and dirGain=1 will give Gain). */
|
||||
ambientGain = minf(sqrtf(2.0f/Device->NumChan), 1.0f);
|
||||
|
||||
// Calculate the 3D-panning gains for the early reflections and late
|
||||
// reverb.
|
||||
length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2];
|
||||
if(length > 1.0f)
|
||||
{
|
||||
length = 1.0f / aluSqrt(length);
|
||||
length = 1.0f / sqrtf(length);
|
||||
earlyPan[0] *= length;
|
||||
earlyPan[1] *= length;
|
||||
earlyPan[2] *= length;
|
||||
@@ -1041,42 +1056,23 @@ static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *Reflection
|
||||
length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2];
|
||||
if(length > 1.0f)
|
||||
{
|
||||
length = 1.0f / aluSqrt(length);
|
||||
length = 1.0f / sqrtf(length);
|
||||
latePan[0] *= length;
|
||||
latePan[1] *= length;
|
||||
latePan[2] *= length;
|
||||
}
|
||||
|
||||
/* This code applies directional reverb just like the mixer applies
|
||||
* directional sources. It diffuses the sound toward all speakers as the
|
||||
* magnitude of the panning vector drops, which is only a rough
|
||||
* approximation of the expansion of sound across the speakers from the
|
||||
* panning direction.
|
||||
*/
|
||||
pos = aluCart2LUTpos(earlyPan[2], earlyPan[0]);
|
||||
ChannelGain = Device->PanningLUT[pos];
|
||||
dirGain = aluSqrt((earlyPan[0] * earlyPan[0]) + (earlyPan[2] * earlyPan[2]));
|
||||
dirGain = sqrtf(earlyPan[0]*earlyPan[0] + earlyPan[2]*earlyPan[2]);
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
State->Early.PanGain[index] = 0.0f;
|
||||
ComputeAngleGains(Device, atan2f(earlyPan[0], earlyPan[2]), (1.0f-dirGain)*F_PI,
|
||||
lerp(ambientGain, 1.0f, dirGain) * Gain, State->Early.PanGain);
|
||||
|
||||
for(index = 0;index < MAXCHANNELS;index++)
|
||||
State->Early.PanGain[index] = 0.0f;
|
||||
for(index = 0;index < Device->NumChan;index++)
|
||||
{
|
||||
enum Channel chan = Device->Speaker2Chan[index];
|
||||
State->Early.PanGain[chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * Gain;
|
||||
}
|
||||
|
||||
|
||||
pos = aluCart2LUTpos(latePan[2], latePan[0]);
|
||||
ChannelGain = Device->PanningLUT[pos];
|
||||
dirGain = aluSqrt((latePan[0] * latePan[0]) + (latePan[2] * latePan[2]));
|
||||
|
||||
for(index = 0;index < MAXCHANNELS;index++)
|
||||
dirGain = sqrtf(latePan[0]*latePan[0] + latePan[2]*latePan[2]);
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
State->Late.PanGain[index] = 0.0f;
|
||||
for(index = 0;index < Device->NumChan;index++)
|
||||
{
|
||||
enum Channel chan = Device->Speaker2Chan[index];
|
||||
State->Late.PanGain[chan] = lerp(ambientGain, ChannelGain[chan], dirGain) * Gain;
|
||||
}
|
||||
ComputeAngleGains(Device, atan2f(latePan[0], latePan[2]), (1.0f-dirGain)*F_PI,
|
||||
lerp(ambientGain, 1.0f, dirGain) * Gain, State->Late.PanGain);
|
||||
}
|
||||
|
||||
// This updates the EAX reverb state. This is called any time the EAX reverb
|
||||
@@ -1163,8 +1159,8 @@ static ALvoid ReverbUpdate(ALeffectState *effect, ALCdevice *Device, const ALeff
|
||||
ALuint index;
|
||||
|
||||
/* Update channel gains */
|
||||
gain *= aluSqrt(2.0f/Device->NumChan) * ReverbBoost;
|
||||
for(index = 0;index < MAXCHANNELS;index++)
|
||||
gain *= sqrtf(2.0f/Device->NumChan) * ReverbBoost;
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
State->Gain[index] = 0.0f;
|
||||
for(index = 0;index < Device->NumChan;index++)
|
||||
{
|
||||
@@ -1258,7 +1254,7 @@ ALeffectState *ReverbCreate(void)
|
||||
State->Late.LpSample[index] = 0.0f;
|
||||
}
|
||||
|
||||
for(index = 0;index < MAXCHANNELS;index++)
|
||||
for(index = 0;index < MaxChannels;index++)
|
||||
{
|
||||
State->Early.PanGain[index] = 0.0f;
|
||||
State->Late.PanGain[index] = 0.0f;
|
||||
|
||||
+20
-4
@@ -25,6 +25,7 @@
|
||||
#include "alMain.h"
|
||||
#include "alThunk.h"
|
||||
|
||||
#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -54,7 +55,7 @@ ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
|
||||
inf->thread = CreateThread(NULL, 0, StarterFunc, inf, 0, &dummy);
|
||||
inf->thread = CreateThread(NULL, THREAD_STACK_SIZE, StarterFunc, inf, 0, &dummy);
|
||||
if(!inf->thread)
|
||||
{
|
||||
free(inf);
|
||||
@@ -98,16 +99,31 @@ static void *StarterFunc(void *ptr)
|
||||
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr)
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
ThreadInfo *inf = malloc(sizeof(ThreadInfo));
|
||||
if(!inf) return NULL;
|
||||
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
if(pthread_create(&inf->thread, NULL, StarterFunc, inf) != 0)
|
||||
if(pthread_attr_init(&attr) != 0)
|
||||
{
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0)
|
||||
{
|
||||
pthread_attr_destroy(&attr);
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inf->func = func;
|
||||
inf->ptr = ptr;
|
||||
if(pthread_create(&inf->thread, &attr, StarterFunc, inf) != 0)
|
||||
{
|
||||
pthread_attr_destroy(&attr);
|
||||
free(inf);
|
||||
return NULL;
|
||||
}
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
return inf;
|
||||
}
|
||||
|
||||
+120
-47
@@ -25,6 +25,7 @@
|
||||
#include <memory.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
@@ -57,6 +58,10 @@ MAKE_FUNC(snd_pcm_hw_params_set_period_time_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_period_size_near);
|
||||
MAKE_FUNC(snd_pcm_hw_params_set_buffer_size_min);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_buffer_time_min);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_buffer_time_max);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_period_time_min);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_period_time_max);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_buffer_size);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_period_size);
|
||||
MAKE_FUNC(snd_pcm_hw_params_get_access);
|
||||
@@ -75,6 +80,7 @@ MAKE_FUNC(snd_pcm_start);
|
||||
MAKE_FUNC(snd_pcm_resume);
|
||||
MAKE_FUNC(snd_pcm_reset);
|
||||
MAKE_FUNC(snd_pcm_wait);
|
||||
MAKE_FUNC(snd_pcm_delay);
|
||||
MAKE_FUNC(snd_pcm_state);
|
||||
MAKE_FUNC(snd_pcm_avail_update);
|
||||
MAKE_FUNC(snd_pcm_areas_silence);
|
||||
@@ -101,6 +107,7 @@ MAKE_FUNC(snd_ctl_card_info);
|
||||
MAKE_FUNC(snd_ctl_card_info_get_name);
|
||||
MAKE_FUNC(snd_ctl_card_info_get_id);
|
||||
MAKE_FUNC(snd_card_next);
|
||||
MAKE_FUNC(snd_config_update_free_global);
|
||||
#undef MAKE_FUNC
|
||||
|
||||
#define snd_strerror psnd_strerror
|
||||
@@ -125,6 +132,10 @@ MAKE_FUNC(snd_card_next);
|
||||
#define snd_pcm_hw_params_set_buffer_size_near psnd_pcm_hw_params_set_buffer_size_near
|
||||
#define snd_pcm_hw_params_set_period_size_near psnd_pcm_hw_params_set_period_size_near
|
||||
#define snd_pcm_hw_params_set_buffer_size_min psnd_pcm_hw_params_set_buffer_size_min
|
||||
#define snd_pcm_hw_params_get_buffer_time_min psnd_pcm_hw_params_get_buffer_time_min
|
||||
#define snd_pcm_hw_params_get_buffer_time_max psnd_pcm_hw_params_get_buffer_time_max
|
||||
#define snd_pcm_hw_params_get_period_time_min psnd_pcm_hw_params_get_period_time_min
|
||||
#define snd_pcm_hw_params_get_period_time_max psnd_pcm_hw_params_get_period_time_max
|
||||
#define snd_pcm_hw_params_get_buffer_size psnd_pcm_hw_params_get_buffer_size
|
||||
#define snd_pcm_hw_params_get_period_size psnd_pcm_hw_params_get_period_size
|
||||
#define snd_pcm_hw_params_get_access psnd_pcm_hw_params_get_access
|
||||
@@ -143,6 +154,7 @@ MAKE_FUNC(snd_card_next);
|
||||
#define snd_pcm_resume psnd_pcm_resume
|
||||
#define snd_pcm_reset psnd_pcm_reset
|
||||
#define snd_pcm_wait psnd_pcm_wait
|
||||
#define snd_pcm_delay psnd_pcm_delay
|
||||
#define snd_pcm_state psnd_pcm_state
|
||||
#define snd_pcm_avail_update psnd_pcm_avail_update
|
||||
#define snd_pcm_areas_silence psnd_pcm_areas_silence
|
||||
@@ -169,6 +181,7 @@ MAKE_FUNC(snd_card_next);
|
||||
#define snd_ctl_card_info_get_name psnd_ctl_card_info_get_name
|
||||
#define snd_ctl_card_info_get_id psnd_ctl_card_info_get_id
|
||||
#define snd_card_next psnd_card_next
|
||||
#define snd_config_update_free_global psnd_config_update_free_global
|
||||
#endif
|
||||
|
||||
|
||||
@@ -211,6 +224,10 @@ static ALCboolean alsa_load(void)
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_near);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_buffer_size_min);
|
||||
LOAD_FUNC(snd_pcm_hw_params_set_period_size_near);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_buffer_time_min);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_buffer_time_max);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_period_time_min);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_period_time_max);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_buffer_size);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_period_size);
|
||||
LOAD_FUNC(snd_pcm_hw_params_get_access);
|
||||
@@ -229,6 +246,7 @@ static ALCboolean alsa_load(void)
|
||||
LOAD_FUNC(snd_pcm_resume);
|
||||
LOAD_FUNC(snd_pcm_reset);
|
||||
LOAD_FUNC(snd_pcm_wait);
|
||||
LOAD_FUNC(snd_pcm_delay);
|
||||
LOAD_FUNC(snd_pcm_state);
|
||||
LOAD_FUNC(snd_pcm_avail_update);
|
||||
LOAD_FUNC(snd_pcm_areas_silence);
|
||||
@@ -255,6 +273,7 @@ static ALCboolean alsa_load(void)
|
||||
LOAD_FUNC(snd_ctl_card_info_get_name);
|
||||
LOAD_FUNC(snd_ctl_card_info_get_id);
|
||||
LOAD_FUNC(snd_card_next);
|
||||
LOAD_FUNC(snd_config_update_free_global);
|
||||
#undef LOAD_FUNC
|
||||
}
|
||||
#endif
|
||||
@@ -434,8 +453,8 @@ static int verify_state(snd_pcm_t *handle)
|
||||
|
||||
static ALuint ALSAProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)Device->ExtraData;
|
||||
const snd_pcm_channel_area_t *areas = NULL;
|
||||
snd_pcm_uframes_t update_size, num_updates;
|
||||
snd_pcm_sframes_t avail, commitres;
|
||||
@@ -445,15 +464,17 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
update_size = pDevice->UpdateSize;
|
||||
num_updates = pDevice->NumUpdates;
|
||||
update_size = Device->UpdateSize;
|
||||
num_updates = Device->NumUpdates;
|
||||
while(!data->killNow)
|
||||
{
|
||||
int state = verify_state(data->pcmHandle);
|
||||
if(state < 0)
|
||||
{
|
||||
ERR("Invalid state detected: %s\n", snd_strerror(state));
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -490,6 +511,7 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
avail -= avail%update_size;
|
||||
|
||||
// it is possible that contiguous areas are smaller, thus we use a loop
|
||||
ALCdevice_Lock(Device);
|
||||
while(avail > 0)
|
||||
{
|
||||
frames = avail;
|
||||
@@ -502,7 +524,7 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
}
|
||||
|
||||
WritePtr = (char*)areas->addr + (offset * areas->step / 8);
|
||||
aluMixData(pDevice, WritePtr, frames);
|
||||
aluMixData(Device, WritePtr, frames);
|
||||
|
||||
commitres = snd_pcm_mmap_commit(data->pcmHandle, offset, frames);
|
||||
if(commitres < 0 || (commitres-frames) != 0)
|
||||
@@ -514,6 +536,7 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
|
||||
avail -= frames;
|
||||
}
|
||||
ALCdevice_Unlock(Device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -521,26 +544,63 @@ static ALuint ALSAProc(ALvoid *ptr)
|
||||
|
||||
static ALuint ALSANoMMapProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
alsa_data *data = (alsa_data*)Device->ExtraData;
|
||||
snd_pcm_uframes_t update_size, num_updates;
|
||||
snd_pcm_sframes_t avail;
|
||||
char *WritePtr;
|
||||
int err;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
update_size = Device->UpdateSize;
|
||||
num_updates = Device->NumUpdates;
|
||||
while(!data->killNow)
|
||||
{
|
||||
int state = verify_state(data->pcmHandle);
|
||||
if(state < 0)
|
||||
{
|
||||
ERR("Invalid state detected: %s\n", snd_strerror(state));
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
avail = snd_pcm_avail_update(data->pcmHandle);
|
||||
if(avail < 0)
|
||||
{
|
||||
ERR("available update failed: %s\n", snd_strerror(avail));
|
||||
continue;
|
||||
}
|
||||
|
||||
if((snd_pcm_uframes_t)avail > update_size*num_updates)
|
||||
{
|
||||
WARN("available samples exceeds the buffer size\n");
|
||||
snd_pcm_reset(data->pcmHandle);
|
||||
continue;
|
||||
}
|
||||
|
||||
if((snd_pcm_uframes_t)avail < update_size)
|
||||
{
|
||||
if(state != SND_PCM_STATE_RUNNING)
|
||||
{
|
||||
err = snd_pcm_start(data->pcmHandle);
|
||||
if(err < 0)
|
||||
{
|
||||
ERR("start failed: %s\n", snd_strerror(err));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(snd_pcm_wait(data->pcmHandle, 1000) == 0)
|
||||
ERR("Wait timeout... buffer size too low?\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ALCdevice_Lock(Device);
|
||||
WritePtr = data->buffer;
|
||||
avail = data->size / snd_pcm_frames_to_bytes(data->pcmHandle, 1);
|
||||
aluMixData(pDevice, WritePtr, avail);
|
||||
avail = snd_pcm_bytes_to_frames(data->pcmHandle, data->size);
|
||||
aluMixData(Device, WritePtr, avail);
|
||||
|
||||
while(avail > 0)
|
||||
{
|
||||
@@ -571,6 +631,7 @@ static ALuint ALSANoMMapProc(ALvoid *ptr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
ALCdevice_Unlock(Device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -609,11 +670,6 @@ static ALCenum alsa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
data = (alsa_data*)calloc(1, sizeof(alsa_data));
|
||||
|
||||
err = snd_pcm_open(&data->pcmHandle, driver, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||
if(err >= 0)
|
||||
{
|
||||
err = snd_pcm_nonblock(data->pcmHandle, 0);
|
||||
if(err < 0) snd_pcm_close(data->pcmHandle);
|
||||
}
|
||||
if(err < 0)
|
||||
{
|
||||
free(data);
|
||||
@@ -621,7 +677,10 @@ static ALCenum alsa_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
/* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */
|
||||
snd_config_update_free_global();
|
||||
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -688,11 +747,7 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
|
||||
/* set interleaved access */
|
||||
if(!allowmmap || snd_pcm_hw_params_set_access(data->pcmHandle, hp, SND_PCM_ACCESS_MMAP_INTERLEAVED) < 0)
|
||||
{
|
||||
if(periods > 2)
|
||||
{
|
||||
periods--;
|
||||
bufferLen = periodLen * periods;
|
||||
}
|
||||
/* No mmap */
|
||||
CHECK(snd_pcm_hw_params_set_access(data->pcmHandle, hp, SND_PCM_ACCESS_RW_INTERLEAVED));
|
||||
}
|
||||
/* test and set format (implicitly sets sample bits) */
|
||||
@@ -750,9 +805,11 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
|
||||
ERR("Failed to disable ALSA resampler\n");
|
||||
CHECK(snd_pcm_hw_params_set_rate_near(data->pcmHandle, hp, &rate, NULL));
|
||||
/* set buffer time (implicitly constrains period/buffer parameters) */
|
||||
CHECK(snd_pcm_hw_params_set_buffer_time_near(data->pcmHandle, hp, &bufferLen, NULL));
|
||||
if(snd_pcm_hw_params_set_buffer_time_near(data->pcmHandle, hp, &bufferLen, NULL) < 0)
|
||||
ERR("snd_pcm_hw_params_set_buffer_time_near failed: %s\n", snd_strerror(err));
|
||||
/* set period time (implicitly sets buffer size/bytes/time and period size/bytes) */
|
||||
CHECK(snd_pcm_hw_params_set_period_time_near(data->pcmHandle, hp, &periodLen, NULL));
|
||||
if(snd_pcm_hw_params_set_period_time_near(data->pcmHandle, hp, &periodLen, NULL) < 0)
|
||||
ERR("snd_pcm_hw_params_set_period_time_near failed: %s\n", snd_strerror(err));
|
||||
/* install and prepare hardware configuration */
|
||||
CHECK(snd_pcm_hw_params(data->pcmHandle, hp));
|
||||
/* retrieve configuration info */
|
||||
@@ -772,12 +829,7 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
|
||||
snd_pcm_sw_params_free(sp);
|
||||
sp = NULL;
|
||||
|
||||
/* Increase periods by one, since the temp buffer counts as an extra
|
||||
* period */
|
||||
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
|
||||
device->NumUpdates = periods+1;
|
||||
else
|
||||
device->NumUpdates = periods;
|
||||
device->NumUpdates = periods;
|
||||
device->UpdateSize = periodSizeInFrames;
|
||||
device->Frequency = rate;
|
||||
|
||||
@@ -862,7 +914,7 @@ static void alsa_stop_playback(ALCdevice *device)
|
||||
}
|
||||
|
||||
|
||||
static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
static ALCenum alsa_open_capture(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
const char *driver = NULL;
|
||||
snd_pcm_hw_params_t *hp;
|
||||
@@ -908,8 +960,11 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
/* Free alsa's global config tree. Otherwise valgrind reports a ton of leaks. */
|
||||
snd_config_update_free_global();
|
||||
|
||||
format = -1;
|
||||
switch(pDevice->FmtType)
|
||||
switch(Device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
format = SND_PCM_FORMAT_S8;
|
||||
@@ -935,9 +990,9 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
}
|
||||
|
||||
funcerr = NULL;
|
||||
bufferSizeInFrames = maxu(pDevice->UpdateSize*pDevice->NumUpdates,
|
||||
100*pDevice->Frequency/1000);
|
||||
periodSizeInFrames = minu(bufferSizeInFrames, 25*pDevice->Frequency/1000);
|
||||
bufferSizeInFrames = maxu(Device->UpdateSize*Device->NumUpdates,
|
||||
100*Device->Frequency/1000);
|
||||
periodSizeInFrames = minu(bufferSizeInFrames, 25*Device->Frequency/1000);
|
||||
|
||||
snd_pcm_hw_params_malloc(&hp);
|
||||
#define CHECK(x) if((funcerr=#x),(err=(x)) < 0) goto error
|
||||
@@ -947,9 +1002,9 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
/* set format (implicitly sets sample bits) */
|
||||
CHECK(snd_pcm_hw_params_set_format(data->pcmHandle, hp, format));
|
||||
/* set channels (implicitly sets frame bits) */
|
||||
CHECK(snd_pcm_hw_params_set_channels(data->pcmHandle, hp, ChannelsFromDevFmt(pDevice->FmtChans)));
|
||||
CHECK(snd_pcm_hw_params_set_channels(data->pcmHandle, hp, ChannelsFromDevFmt(Device->FmtChans)));
|
||||
/* set rate (implicitly constrains period/buffer parameters) */
|
||||
CHECK(snd_pcm_hw_params_set_rate(data->pcmHandle, hp, pDevice->Frequency, 0));
|
||||
CHECK(snd_pcm_hw_params_set_rate(data->pcmHandle, hp, Device->Frequency, 0));
|
||||
/* set buffer size in frame units (implicitly sets period size/bytes/time and buffer time/bytes) */
|
||||
if(snd_pcm_hw_params_set_buffer_size_min(data->pcmHandle, hp, &bufferSizeInFrames) < 0)
|
||||
{
|
||||
@@ -969,8 +1024,8 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
|
||||
if(needring)
|
||||
{
|
||||
data->ring = CreateRingBuffer(FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType),
|
||||
pDevice->UpdateSize*pDevice->NumUpdates);
|
||||
data->ring = CreateRingBuffer(FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType),
|
||||
Device->UpdateSize*Device->NumUpdates);
|
||||
if(!data->ring)
|
||||
{
|
||||
ERR("ring buffer create failed\n");
|
||||
@@ -986,9 +1041,9 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
}
|
||||
}
|
||||
|
||||
pDevice->szDeviceName = strdup(deviceName);
|
||||
Device->DeviceName = strdup(deviceName);
|
||||
|
||||
pDevice->ExtraData = data;
|
||||
Device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
error:
|
||||
@@ -1001,20 +1056,20 @@ error2:
|
||||
snd_pcm_close(data->pcmHandle);
|
||||
free(data);
|
||||
|
||||
pDevice->ExtraData = NULL;
|
||||
Device->ExtraData = NULL;
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void alsa_close_capture(ALCdevice *pDevice)
|
||||
static void alsa_close_capture(ALCdevice *Device)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)pDevice->ExtraData;
|
||||
alsa_data *data = (alsa_data*)Device->ExtraData;
|
||||
|
||||
snd_pcm_close(data->pcmHandle);
|
||||
DestroyRingBuffer(data->ring);
|
||||
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
pDevice->ExtraData = NULL;
|
||||
Device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void alsa_start_capture(ALCdevice *Device)
|
||||
@@ -1210,6 +1265,21 @@ static void alsa_stop_capture(ALCdevice *Device)
|
||||
}
|
||||
|
||||
|
||||
static ALint64 alsa_get_latency(ALCdevice *device)
|
||||
{
|
||||
alsa_data *data = (alsa_data*)device->ExtraData;
|
||||
snd_pcm_sframes_t delay = 0;
|
||||
int err;
|
||||
|
||||
if((err=snd_pcm_delay(data->pcmHandle, &delay)) < 0)
|
||||
{
|
||||
ERR("Failed to get pcm delay: %s\n", snd_strerror(err));
|
||||
return 0;
|
||||
}
|
||||
return maxi64((ALint64)delay*1000000000/device->Frequency, 0);
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs alsa_funcs = {
|
||||
alsa_open_playback,
|
||||
alsa_close_playback,
|
||||
@@ -1221,7 +1291,10 @@ static const BackendFuncs alsa_funcs = {
|
||||
alsa_start_capture,
|
||||
alsa_stop_capture,
|
||||
alsa_capture_samples,
|
||||
alsa_available_samples
|
||||
alsa_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
alsa_get_latency
|
||||
};
|
||||
|
||||
ALCboolean alc_alsa_init(BackendFuncs *func_list)
|
||||
@@ -1278,7 +1351,7 @@ void alc_alsa_probe(enum DevProbe type)
|
||||
allDevNameMap = probe_devices(SND_PCM_STREAM_PLAYBACK, &numDevNames);
|
||||
|
||||
for(i = 0;i < numDevNames;++i)
|
||||
AppendAllDeviceList(allDevNameMap[i].name);
|
||||
AppendAllDevicesList(allDevNameMap[i].name);
|
||||
break;
|
||||
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
|
||||
+20
-15
@@ -25,8 +25,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <unistd.h>
|
||||
@@ -181,7 +180,7 @@ static ALCenum ca_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -277,38 +276,41 @@ static ALCboolean ca_reset_playback(ALCdevice *device)
|
||||
/* use channel count and sample rate from the default output unit's current
|
||||
* parameters, but reset everything else */
|
||||
streamFormat.mFramesPerPacket = 1;
|
||||
streamFormat.mFormatFlags = 0;
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtUByte:
|
||||
device->FmtType = DevFmtByte;
|
||||
/* fall-through */
|
||||
case DevFmtByte:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 8;
|
||||
streamFormat.mBytesPerPacket = streamFormat.mChannelsPerFrame;
|
||||
streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame;
|
||||
break;
|
||||
case DevFmtUShort:
|
||||
case DevFmtFloat:
|
||||
device->FmtType = DevFmtShort;
|
||||
/* fall-through */
|
||||
case DevFmtShort:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 16;
|
||||
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
|
||||
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
|
||||
break;
|
||||
case DevFmtUInt:
|
||||
device->FmtType = DevFmtInt;
|
||||
/* fall-through */
|
||||
case DevFmtInt:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||
streamFormat.mBitsPerChannel = 32;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat;
|
||||
streamFormat.mBitsPerChannel = 32;
|
||||
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
|
||||
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
|
||||
break;
|
||||
}
|
||||
streamFormat.mBytesPerFrame = streamFormat.mChannelsPerFrame *
|
||||
streamFormat.mBitsPerChannel / 8;
|
||||
streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame;
|
||||
streamFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |
|
||||
kAudioFormatFlagsNativeEndian |
|
||||
kLinearPCMFormatFlagIsPacked;
|
||||
streamFormat.mFormatFlags |= kAudioFormatFlagsNativeEndian |
|
||||
kLinearPCMFormatFlagIsPacked;
|
||||
|
||||
err = AudioUnitSetProperty(data->audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamFormat, sizeof(AudioStreamBasicDescription));
|
||||
if(err != noErr)
|
||||
@@ -674,7 +676,10 @@ static const BackendFuncs ca_funcs = {
|
||||
ca_start_capture,
|
||||
ca_stop_capture,
|
||||
ca_capture_samples,
|
||||
ca_available_samples
|
||||
ca_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_ca_init(BackendFuncs *func_list)
|
||||
@@ -692,7 +697,7 @@ void alc_ca_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(ca_device);
|
||||
AppendAllDevicesList(ca_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
AppendCaptureDeviceList(ca_device);
|
||||
|
||||
+173
-162
@@ -33,8 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifndef DSSPEAKER_5POINT1
|
||||
#define DSSPEAKER_5POINT1 6
|
||||
@@ -61,11 +60,11 @@ static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA pDSEnum
|
||||
|
||||
typedef struct {
|
||||
// DirectSound Playback Device
|
||||
IDirectSound *lpDS;
|
||||
IDirectSoundBuffer *DSpbuffer;
|
||||
IDirectSoundBuffer *DSsbuffer;
|
||||
IDirectSoundNotify *DSnotify;
|
||||
HANDLE hNotifyEvent;
|
||||
IDirectSound *DS;
|
||||
IDirectSoundBuffer *PrimaryBuffer;
|
||||
IDirectSoundBuffer *Buffer;
|
||||
IDirectSoundNotify *Notifies;
|
||||
HANDLE NotifyEvent;
|
||||
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
@@ -73,11 +72,11 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
// DirectSound Capture Device
|
||||
IDirectSoundCapture *lpDSC;
|
||||
IDirectSoundCapture *DSC;
|
||||
IDirectSoundCaptureBuffer *DSCbuffer;
|
||||
DWORD dwBufferBytes;
|
||||
DWORD dwCursor;
|
||||
RingBuffer *pRing;
|
||||
DWORD BufferBytes;
|
||||
DWORD Cursor;
|
||||
RingBuffer *Ring;
|
||||
} DSoundCaptureData;
|
||||
|
||||
|
||||
@@ -224,8 +223,8 @@ static BOOL CALLBACK DSoundEnumCaptureDevices(LPGUID guid, LPCSTR desc, LPCSTR d
|
||||
|
||||
static ALuint DSoundPlaybackProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
DSoundPlaybackData *pData = (DSoundPlaybackData*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
DSoundPlaybackData *data = (DSoundPlaybackData*)Device->ExtraData;
|
||||
DSBCAPS DSBCaps;
|
||||
DWORD LastCursor = 0;
|
||||
DWORD PlayCursor;
|
||||
@@ -241,39 +240,43 @@ static ALuint DSoundPlaybackProc(ALvoid *ptr)
|
||||
|
||||
memset(&DSBCaps, 0, sizeof(DSBCaps));
|
||||
DSBCaps.dwSize = sizeof(DSBCaps);
|
||||
err = IDirectSoundBuffer_GetCaps(pData->DSsbuffer, &DSBCaps);
|
||||
err = IDirectSoundBuffer_GetCaps(data->Buffer, &DSBCaps);
|
||||
if(FAILED(err))
|
||||
{
|
||||
ERR("Failed to get buffer caps: 0x%lx\n", err);
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
FragSize = pDevice->UpdateSize * FrameSize;
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
FragSize = Device->UpdateSize * FrameSize;
|
||||
|
||||
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
|
||||
while(!pData->killNow)
|
||||
IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &LastCursor, NULL);
|
||||
while(!data->killNow)
|
||||
{
|
||||
// Get current play cursor
|
||||
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
|
||||
IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &PlayCursor, NULL);
|
||||
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
|
||||
|
||||
if(avail < FragSize)
|
||||
{
|
||||
if(!Playing)
|
||||
{
|
||||
err = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);
|
||||
err = IDirectSoundBuffer_Play(data->Buffer, 0, 0, DSBPLAY_LOOPING);
|
||||
if(FAILED(err))
|
||||
{
|
||||
ERR("Failed to play buffer: 0x%lx\n", err);
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
return 1;
|
||||
}
|
||||
Playing = TRUE;
|
||||
}
|
||||
|
||||
avail = WaitForSingleObjectEx(pData->hNotifyEvent, 2000, FALSE);
|
||||
avail = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE);
|
||||
if(avail != WAIT_OBJECT_0)
|
||||
ERR("WaitForSingleObjectEx error: 0x%lx\n", avail);
|
||||
continue;
|
||||
@@ -283,18 +286,18 @@ static ALuint DSoundPlaybackProc(ALvoid *ptr)
|
||||
// Lock output buffer
|
||||
WriteCnt1 = 0;
|
||||
WriteCnt2 = 0;
|
||||
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
|
||||
err = IDirectSoundBuffer_Lock(data->Buffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
|
||||
|
||||
// If the buffer is lost, restore it and lock
|
||||
if(err == DSERR_BUFFERLOST)
|
||||
{
|
||||
WARN("Buffer lost, restoring...\n");
|
||||
err = IDirectSoundBuffer_Restore(pData->DSsbuffer);
|
||||
err = IDirectSoundBuffer_Restore(data->Buffer);
|
||||
if(SUCCEEDED(err))
|
||||
{
|
||||
Playing = FALSE;
|
||||
LastCursor = 0;
|
||||
err = IDirectSoundBuffer_Lock(pData->DSsbuffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
|
||||
err = IDirectSoundBuffer_Lock(data->Buffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,16 +305,18 @@ static ALuint DSoundPlaybackProc(ALvoid *ptr)
|
||||
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);
|
||||
aluMixData(Device, WritePtr1, WriteCnt1/FrameSize);
|
||||
aluMixData(Device, WritePtr2, WriteCnt2/FrameSize);
|
||||
|
||||
// Unlock output buffer only when successfully locked
|
||||
IDirectSoundBuffer_Unlock(pData->DSsbuffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
|
||||
IDirectSoundBuffer_Unlock(data->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Buffer lock error: %#lx\n", err);
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -325,7 +330,7 @@ static ALuint DSoundPlaybackProc(ALvoid *ptr)
|
||||
|
||||
static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
DSoundPlaybackData *pData = NULL;
|
||||
DSoundPlaybackData *data = NULL;
|
||||
LPGUID guid = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
@@ -358,59 +363,59 @@ static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
|
||||
}
|
||||
|
||||
//Initialise requested device
|
||||
pData = calloc(1, sizeof(DSoundPlaybackData));
|
||||
if(!pData)
|
||||
data = calloc(1, sizeof(DSoundPlaybackData));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
|
||||
hr = DS_OK;
|
||||
pData->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(pData->hNotifyEvent == NULL)
|
||||
data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->NotifyEvent == NULL)
|
||||
hr = E_FAIL;
|
||||
|
||||
//DirectSound Init code
|
||||
if(SUCCEEDED(hr))
|
||||
hr = DirectSoundCreate(guid, &pData->lpDS, NULL);
|
||||
hr = DirectSoundCreate(guid, &data->DS, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
|
||||
hr = IDirectSound_SetCooperativeLevel(data->DS, GetForegroundWindow(), DSSCL_PRIORITY);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(pData->lpDS)
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
if(pData->hNotifyEvent)
|
||||
CloseHandle(pData->hNotifyEvent);
|
||||
free(pData);
|
||||
if(data->DS)
|
||||
IDirectSound_Release(data->DS);
|
||||
if(data->NotifyEvent)
|
||||
CloseHandle(data->NotifyEvent);
|
||||
free(data);
|
||||
ERR("Device init failed: 0x%08lx\n", hr);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = pData;
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void DSoundClosePlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundPlaybackData *pData = device->ExtraData;
|
||||
DSoundPlaybackData *data = device->ExtraData;
|
||||
|
||||
if(pData->DSnotify)
|
||||
IDirectSoundNotify_Release(pData->DSnotify);
|
||||
pData->DSnotify = NULL;
|
||||
if(pData->DSsbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
pData->DSsbuffer = NULL;
|
||||
if(pData->DSpbuffer != NULL)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
pData->DSpbuffer = NULL;
|
||||
if(data->Notifies)
|
||||
IDirectSoundNotify_Release(data->Notifies);
|
||||
data->Notifies = NULL;
|
||||
if(data->Buffer)
|
||||
IDirectSoundBuffer_Release(data->Buffer);
|
||||
data->Buffer = NULL;
|
||||
if(data->PrimaryBuffer != NULL)
|
||||
IDirectSoundBuffer_Release(data->PrimaryBuffer);
|
||||
data->PrimaryBuffer = NULL;
|
||||
|
||||
IDirectSound_Release(pData->lpDS);
|
||||
CloseHandle(pData->hNotifyEvent);
|
||||
free(pData);
|
||||
IDirectSound_Release(data->DS);
|
||||
CloseHandle(data->NotifyEvent);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static ALCboolean DSoundResetPlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundPlaybackData *pData = (DSoundPlaybackData*)device->ExtraData;
|
||||
DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData;
|
||||
DSBUFFERDESC DSBDescription;
|
||||
WAVEFORMATEXTENSIBLE OutputType;
|
||||
DWORD speakers;
|
||||
@@ -418,21 +423,25 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
|
||||
|
||||
memset(&OutputType, 0, sizeof(OutputType));
|
||||
|
||||
if(pData->DSnotify)
|
||||
IDirectSoundNotify_Release(pData->DSnotify);
|
||||
pData->DSnotify = NULL;
|
||||
if(pData->DSsbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
pData->DSsbuffer = NULL;
|
||||
if(pData->DSpbuffer != NULL)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
pData->DSpbuffer = NULL;
|
||||
if(data->Notifies)
|
||||
IDirectSoundNotify_Release(data->Notifies);
|
||||
data->Notifies = NULL;
|
||||
if(data->Buffer)
|
||||
IDirectSoundBuffer_Release(data->Buffer);
|
||||
data->Buffer = NULL;
|
||||
if(data->PrimaryBuffer != NULL)
|
||||
IDirectSoundBuffer_Release(data->PrimaryBuffer);
|
||||
data->PrimaryBuffer = NULL;
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
case DevFmtByte:
|
||||
device->FmtType = DevFmtUByte;
|
||||
break;
|
||||
case DevFmtFloat:
|
||||
if((device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
|
||||
break;
|
||||
/* fall-through */
|
||||
case DevFmtUShort:
|
||||
device->FmtType = DevFmtShort;
|
||||
break;
|
||||
@@ -442,11 +451,10 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
|
||||
case DevFmtUByte:
|
||||
case DevFmtShort:
|
||||
case DevFmtInt:
|
||||
case DevFmtFloat:
|
||||
break;
|
||||
}
|
||||
|
||||
hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
|
||||
hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
|
||||
@@ -539,21 +547,21 @@ retry_open:
|
||||
else
|
||||
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
|
||||
if(pData->DSpbuffer)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
pData->DSpbuffer = NULL;
|
||||
if(data->PrimaryBuffer)
|
||||
IDirectSoundBuffer_Release(data->PrimaryBuffer);
|
||||
data->PrimaryBuffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(SUCCEEDED(hr))
|
||||
if(SUCCEEDED(hr) && !data->PrimaryBuffer)
|
||||
{
|
||||
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
|
||||
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
|
||||
DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
|
||||
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
|
||||
hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->PrimaryBuffer, NULL);
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
|
||||
hr = IDirectSoundBuffer_SetFormat(data->PrimaryBuffer,&OutputType.Format);
|
||||
}
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
@@ -571,7 +579,7 @@ retry_open:
|
||||
DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
|
||||
OutputType.Format.nBlockAlign;
|
||||
DSBDescription.lpwfxFormat=&OutputType.Format;
|
||||
hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
|
||||
hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->Buffer, NULL);
|
||||
if(FAILED(hr) && device->FmtType == DevFmtFloat)
|
||||
{
|
||||
device->FmtType = DevFmtShort;
|
||||
@@ -581,7 +589,7 @@ retry_open:
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = IDirectSoundBuffer_QueryInterface(pData->DSsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&pData->DSnotify);
|
||||
hr = IDirectSoundBuffer_QueryInterface(data->Buffer, &IID_IDirectSoundNotify, (LPVOID *)&data->Notifies);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
DSBPOSITIONNOTIFY notifies[MAX_UPDATES];
|
||||
@@ -591,28 +599,28 @@ retry_open:
|
||||
{
|
||||
notifies[i].dwOffset = i * device->UpdateSize *
|
||||
OutputType.Format.nBlockAlign;
|
||||
notifies[i].hEventNotify = pData->hNotifyEvent;
|
||||
notifies[i].hEventNotify = data->NotifyEvent;
|
||||
}
|
||||
if(IDirectSoundNotify_SetNotificationPositions(pData->DSnotify, device->NumUpdates, notifies) != DS_OK)
|
||||
if(IDirectSoundNotify_SetNotificationPositions(data->Notifies, device->NumUpdates, notifies) != DS_OK)
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(pData->DSnotify != NULL)
|
||||
IDirectSoundNotify_Release(pData->DSnotify);
|
||||
pData->DSnotify = NULL;
|
||||
if(pData->DSsbuffer != NULL)
|
||||
IDirectSoundBuffer_Release(pData->DSsbuffer);
|
||||
pData->DSsbuffer = NULL;
|
||||
if(pData->DSpbuffer != NULL)
|
||||
IDirectSoundBuffer_Release(pData->DSpbuffer);
|
||||
pData->DSpbuffer = NULL;
|
||||
if(data->Notifies != NULL)
|
||||
IDirectSoundNotify_Release(data->Notifies);
|
||||
data->Notifies = NULL;
|
||||
if(data->Buffer != NULL)
|
||||
IDirectSoundBuffer_Release(data->Buffer);
|
||||
data->Buffer = NULL;
|
||||
if(data->PrimaryBuffer != NULL)
|
||||
IDirectSoundBuffer_Release(data->PrimaryBuffer);
|
||||
data->PrimaryBuffer = NULL;
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
ResetEvent(pData->hNotifyEvent);
|
||||
ResetEvent(data->NotifyEvent);
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
|
||||
return ALC_TRUE;
|
||||
@@ -620,10 +628,10 @@ retry_open:
|
||||
|
||||
static ALCboolean DSoundStartPlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundPlaybackData *pData = (DSoundPlaybackData*)device->ExtraData;
|
||||
DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData;
|
||||
|
||||
pData->thread = StartThread(DSoundPlaybackProc, device);
|
||||
if(pData->thread == NULL)
|
||||
data->thread = StartThread(DSoundPlaybackProc, device);
|
||||
if(data->thread == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
return ALC_TRUE;
|
||||
@@ -631,23 +639,23 @@ static ALCboolean DSoundStartPlayback(ALCdevice *device)
|
||||
|
||||
static void DSoundStopPlayback(ALCdevice *device)
|
||||
{
|
||||
DSoundPlaybackData *pData = device->ExtraData;
|
||||
DSoundPlaybackData *data = device->ExtraData;
|
||||
|
||||
if(!pData->thread)
|
||||
if(!data->thread)
|
||||
return;
|
||||
|
||||
pData->killNow = 1;
|
||||
StopThread(pData->thread);
|
||||
pData->thread = NULL;
|
||||
data->killNow = 1;
|
||||
StopThread(data->thread);
|
||||
data->thread = NULL;
|
||||
|
||||
pData->killNow = 0;
|
||||
IDirectSoundBuffer_Stop(pData->DSsbuffer);
|
||||
data->killNow = 0;
|
||||
IDirectSoundBuffer_Stop(data->Buffer);
|
||||
}
|
||||
|
||||
|
||||
static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
DSoundCaptureData *pData = NULL;
|
||||
DSoundCaptureData *data = NULL;
|
||||
WAVEFORMATEXTENSIBLE InputType;
|
||||
DSCBUFFERDESC DSCBDescription;
|
||||
LPGUID guid = NULL;
|
||||
@@ -702,15 +710,15 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
|
||||
}
|
||||
|
||||
//Initialise requested device
|
||||
pData = calloc(1, sizeof(DSoundCaptureData));
|
||||
if(!pData)
|
||||
data = calloc(1, sizeof(DSoundCaptureData));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
|
||||
hr = DS_OK;
|
||||
|
||||
//DirectSoundCapture Init code
|
||||
if(SUCCEEDED(hr))
|
||||
hr = DirectSoundCaptureCreate(guid, &pData->lpDSC, NULL);
|
||||
hr = DirectSoundCaptureCreate(guid, &data->DSC, NULL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
memset(&InputType, 0, sizeof(InputType));
|
||||
@@ -795,12 +803,12 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
|
||||
DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign;
|
||||
DSCBDescription.lpwfxFormat = &InputType.Format;
|
||||
|
||||
hr = IDirectSoundCapture_CreateCaptureBuffer(pData->lpDSC, &DSCBDescription, &pData->DSCbuffer, NULL);
|
||||
hr = IDirectSoundCapture_CreateCaptureBuffer(data->DSC, &DSCBDescription, &data->DSCbuffer, NULL);
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
pData->pRing = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates);
|
||||
if(pData->pRing == NULL)
|
||||
data->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates);
|
||||
if(data->Ring == NULL)
|
||||
hr = DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
@@ -808,55 +816,55 @@ static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
ERR("Device init failed: 0x%08lx\n", hr);
|
||||
|
||||
DestroyRingBuffer(pData->pRing);
|
||||
pData->pRing = NULL;
|
||||
if(pData->DSCbuffer != NULL)
|
||||
IDirectSoundCaptureBuffer_Release(pData->DSCbuffer);
|
||||
pData->DSCbuffer = NULL;
|
||||
if(pData->lpDSC)
|
||||
IDirectSoundCapture_Release(pData->lpDSC);
|
||||
pData->lpDSC = NULL;
|
||||
DestroyRingBuffer(data->Ring);
|
||||
data->Ring = NULL;
|
||||
if(data->DSCbuffer != NULL)
|
||||
IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
|
||||
data->DSCbuffer = NULL;
|
||||
if(data->DSC)
|
||||
IDirectSoundCapture_Release(data->DSC);
|
||||
data->DSC = NULL;
|
||||
|
||||
free(pData);
|
||||
free(data);
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
pData->dwBufferBytes = DSCBDescription.dwBufferBytes;
|
||||
data->BufferBytes = DSCBDescription.dwBufferBytes;
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->ExtraData = pData;
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static void DSoundCloseCapture(ALCdevice *device)
|
||||
{
|
||||
DSoundCaptureData *pData = device->ExtraData;
|
||||
DSoundCaptureData *data = device->ExtraData;
|
||||
|
||||
DestroyRingBuffer(pData->pRing);
|
||||
pData->pRing = NULL;
|
||||
DestroyRingBuffer(data->Ring);
|
||||
data->Ring = NULL;
|
||||
|
||||
if(pData->DSCbuffer != NULL)
|
||||
if(data->DSCbuffer != NULL)
|
||||
{
|
||||
IDirectSoundCaptureBuffer_Stop(pData->DSCbuffer);
|
||||
IDirectSoundCaptureBuffer_Release(pData->DSCbuffer);
|
||||
pData->DSCbuffer = NULL;
|
||||
IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
|
||||
IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
|
||||
data->DSCbuffer = NULL;
|
||||
}
|
||||
|
||||
IDirectSoundCapture_Release(pData->lpDSC);
|
||||
pData->lpDSC = NULL;
|
||||
IDirectSoundCapture_Release(data->DSC);
|
||||
data->DSC = NULL;
|
||||
|
||||
free(pData);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void DSoundStartCapture(ALCdevice *device)
|
||||
{
|
||||
DSoundCaptureData *pData = device->ExtraData;
|
||||
DSoundCaptureData *data = device->ExtraData;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDirectSoundCaptureBuffer_Start(pData->DSCbuffer, DSCBSTART_LOOPING);
|
||||
hr = IDirectSoundCaptureBuffer_Start(data->DSCbuffer, DSCBSTART_LOOPING);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("start failed: 0x%08lx\n", hr);
|
||||
@@ -866,10 +874,10 @@ static void DSoundStartCapture(ALCdevice *device)
|
||||
|
||||
static void DSoundStopCapture(ALCdevice *device)
|
||||
{
|
||||
DSoundCaptureData *pData = device->ExtraData;
|
||||
DSoundCaptureData *data = device->ExtraData;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDirectSoundCaptureBuffer_Stop(pData->DSCbuffer);
|
||||
hr = IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("stop failed: 0x%08lx\n", hr);
|
||||
@@ -877,61 +885,61 @@ static void DSoundStopCapture(ALCdevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static ALCenum DSoundCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
static ALCenum DSoundCaptureSamples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
DSoundCaptureData *pData = pDevice->ExtraData;
|
||||
ReadRingBuffer(pData->pRing, pBuffer, lSamples);
|
||||
DSoundCaptureData *data = Device->ExtraData;
|
||||
ReadRingBuffer(data->Ring, pBuffer, lSamples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint DSoundAvailableSamples(ALCdevice *pDevice)
|
||||
static ALCuint DSoundAvailableSamples(ALCdevice *Device)
|
||||
{
|
||||
DSoundCaptureData *pData = pDevice->ExtraData;
|
||||
DWORD dwRead, dwCursor, dwBufferBytes, dwNumBytes;
|
||||
void *pvAudio1, *pvAudio2;
|
||||
DWORD dwAudioBytes1, dwAudioBytes2;
|
||||
DSoundCaptureData *data = Device->ExtraData;
|
||||
DWORD ReadCursor, LastCursor, BufferBytes, NumBytes;
|
||||
VOID *ReadPtr1, *ReadPtr2;
|
||||
DWORD ReadCnt1, ReadCnt2;
|
||||
DWORD FrameSize;
|
||||
HRESULT hr;
|
||||
|
||||
if(!pDevice->Connected)
|
||||
if(!Device->Connected)
|
||||
goto done;
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
dwBufferBytes = pData->dwBufferBytes;
|
||||
dwCursor = pData->dwCursor;
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
BufferBytes = data->BufferBytes;
|
||||
LastCursor = data->Cursor;
|
||||
|
||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pData->DSCbuffer, NULL, &dwRead);
|
||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(data->DSCbuffer, NULL, &ReadCursor);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
dwNumBytes = (dwBufferBytes + dwRead - dwCursor) % dwBufferBytes;
|
||||
if(dwNumBytes == 0)
|
||||
NumBytes = (ReadCursor-LastCursor + BufferBytes) % BufferBytes;
|
||||
if(NumBytes == 0)
|
||||
goto done;
|
||||
hr = IDirectSoundCaptureBuffer_Lock(pData->DSCbuffer,
|
||||
dwCursor, dwNumBytes,
|
||||
&pvAudio1, &dwAudioBytes1,
|
||||
&pvAudio2, &dwAudioBytes2, 0);
|
||||
hr = IDirectSoundCaptureBuffer_Lock(data->DSCbuffer, LastCursor, NumBytes,
|
||||
&ReadPtr1, &ReadCnt1,
|
||||
&ReadPtr2, &ReadCnt2, 0);
|
||||
}
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
WriteRingBuffer(pData->pRing, pvAudio1, dwAudioBytes1/FrameSize);
|
||||
if(pvAudio2 != NULL)
|
||||
WriteRingBuffer(pData->pRing, pvAudio2, dwAudioBytes2/FrameSize);
|
||||
hr = IDirectSoundCaptureBuffer_Unlock(pData->DSCbuffer,
|
||||
pvAudio1, dwAudioBytes1,
|
||||
pvAudio2, dwAudioBytes2);
|
||||
pData->dwCursor = (dwCursor + dwAudioBytes1 + dwAudioBytes2) % dwBufferBytes;
|
||||
WriteRingBuffer(data->Ring, ReadPtr1, ReadCnt1/FrameSize);
|
||||
if(ReadPtr2 != NULL)
|
||||
WriteRingBuffer(data->Ring, ReadPtr2, ReadCnt2/FrameSize);
|
||||
hr = IDirectSoundCaptureBuffer_Unlock(data->DSCbuffer,
|
||||
ReadPtr1, ReadCnt1,
|
||||
ReadPtr2, ReadCnt2);
|
||||
data->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("update failed: 0x%08lx\n", hr);
|
||||
aluHandleDisconnect(pDevice);
|
||||
aluHandleDisconnect(Device);
|
||||
}
|
||||
|
||||
done:
|
||||
return RingBufferSize(pData->pRing);
|
||||
return RingBufferSize(data->Ring);
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs DSoundFuncs = {
|
||||
DSoundOpenPlayback,
|
||||
DSoundClosePlayback,
|
||||
@@ -943,7 +951,10 @@ static const BackendFuncs DSoundFuncs = {
|
||||
DSoundStartCapture,
|
||||
DSoundStopCapture,
|
||||
DSoundCaptureSamples,
|
||||
DSoundAvailableSamples
|
||||
DSoundAvailableSamples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
|
||||
@@ -996,7 +1007,7 @@ void alcDSoundProbe(enum DevProbe type)
|
||||
else
|
||||
{
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
AppendAllDeviceList(PlaybackDeviceList[i].name);
|
||||
AppendAllDevicesList(PlaybackDeviceList[i].name);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
static ALCenum loopback_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
{
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ static void loopback_stop_playback(ALCdevice *device)
|
||||
(void)device;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs loopback_funcs = {
|
||||
loopback_open_playback,
|
||||
loopback_close_playback,
|
||||
@@ -65,7 +66,10 @@ static const BackendFuncs loopback_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_loopback_init(BackendFuncs *func_list)
|
||||
|
||||
+43
-25
@@ -28,6 +28,7 @@
|
||||
#include <mmdeviceapi.h>
|
||||
#include <audioclient.h>
|
||||
#include <cguid.h>
|
||||
#include <devpropdef.h>
|
||||
#include <mmreg.h>
|
||||
#include <propsys.h>
|
||||
#include <propkey.h>
|
||||
@@ -38,13 +39,14 @@
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
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);
|
||||
|
||||
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14);
|
||||
|
||||
#define MONO SPEAKER_FRONT_CENTER
|
||||
#define STEREO (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT)
|
||||
#define QUAD (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
|
||||
@@ -60,10 +62,12 @@ typedef struct {
|
||||
IMMDevice *mmdev;
|
||||
IAudioClient *client;
|
||||
IAudioRenderClient *render;
|
||||
HANDLE hNotifyEvent;
|
||||
HANDLE NotifyEvent;
|
||||
|
||||
HANDLE MsgEvent;
|
||||
|
||||
volatile UINT32 Padding;
|
||||
|
||||
volatile int killNow;
|
||||
ALvoid *thread;
|
||||
} MMDevApiData;
|
||||
@@ -225,37 +229,34 @@ static ALuint MMDevApiProc(ALvoid *ptr)
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("CoInitialize(NULL) failed: 0x%08lx\n", hr);
|
||||
ALCdevice_Lock(device);
|
||||
aluHandleDisconnect(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
hr = IAudioClient_GetBufferSize(data->client, &buffer_len);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to get audio buffer size: 0x%08lx\n", hr);
|
||||
aluHandleDisconnect(device);
|
||||
CoUninitialize();
|
||||
ALCdevice_Unlock(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
update_size = device->UpdateSize;
|
||||
buffer_len = update_size * device->NumUpdates;
|
||||
while(!data->killNow)
|
||||
{
|
||||
hr = IAudioClient_GetCurrentPadding(data->client, &written);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to get padding: 0x%08lx\n", hr);
|
||||
ALCdevice_Lock(device);
|
||||
aluHandleDisconnect(device);
|
||||
ALCdevice_Unlock(device);
|
||||
break;
|
||||
}
|
||||
data->Padding = written;
|
||||
|
||||
len = buffer_len - written;
|
||||
if(len < update_size)
|
||||
{
|
||||
DWORD res;
|
||||
res = WaitForSingleObjectEx(data->hNotifyEvent, 2000, FALSE);
|
||||
res = WaitForSingleObjectEx(data->NotifyEvent, 2000, FALSE);
|
||||
if(res != WAIT_OBJECT_0)
|
||||
ERR("WaitForSingleObjectEx error: 0x%lx\n", res);
|
||||
continue;
|
||||
@@ -265,16 +266,22 @@ static ALuint MMDevApiProc(ALvoid *ptr)
|
||||
hr = IAudioRenderClient_GetBuffer(data->render, len, &buffer);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
ALCdevice_Lock(device);
|
||||
aluMixData(device, buffer, len);
|
||||
data->Padding = written + len;
|
||||
ALCdevice_Unlock(device);
|
||||
hr = IAudioRenderClient_ReleaseBuffer(data->render, len, 0);
|
||||
}
|
||||
if(FAILED(hr))
|
||||
{
|
||||
ERR("Failed to buffer data: 0x%08lx\n", hr);
|
||||
ALCdevice_Lock(device);
|
||||
aluHandleDisconnect(device);
|
||||
ALCdevice_Unlock(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
data->Padding = 0;
|
||||
|
||||
CoUninitialize();
|
||||
return 0;
|
||||
@@ -622,7 +629,7 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
data->client = ptr;
|
||||
device->szDeviceName = get_device_name(data->mmdev);
|
||||
device->DeviceName = get_device_name(data->mmdev);
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
@@ -651,8 +658,8 @@ static DWORD CALLBACK MMDevApiMsgProc(void *ptr)
|
||||
device = (ALCdevice*)msg.lParam;
|
||||
data = device->ExtraData;
|
||||
|
||||
ResetEvent(data->hNotifyEvent);
|
||||
hr = IAudioClient_SetEventHandle(data->client, data->hNotifyEvent);
|
||||
ResetEvent(data->NotifyEvent);
|
||||
hr = IAudioClient_SetEventHandle(data->client, data->NotifyEvent);
|
||||
if(FAILED(hr))
|
||||
ERR("Failed to set event handle: 0x%08lx\n", hr);
|
||||
else
|
||||
@@ -820,9 +827,9 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName
|
||||
device->ExtraData = data;
|
||||
|
||||
hr = S_OK;
|
||||
data->hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
data->MsgEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->hNotifyEvent == NULL || data->MsgEvent == NULL)
|
||||
if(data->NotifyEvent == NULL || data->MsgEvent == NULL)
|
||||
hr = E_FAIL;
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
@@ -862,9 +869,9 @@ static ALCenum MMDevApiOpenPlayback(ALCdevice *device, const ALCchar *deviceName
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(data->hNotifyEvent != NULL)
|
||||
CloseHandle(data->hNotifyEvent);
|
||||
data->hNotifyEvent = NULL;
|
||||
if(data->NotifyEvent != NULL)
|
||||
CloseHandle(data->NotifyEvent);
|
||||
data->NotifyEvent = NULL;
|
||||
if(data->MsgEvent != NULL)
|
||||
CloseHandle(data->MsgEvent);
|
||||
data->MsgEvent = NULL;
|
||||
@@ -890,8 +897,8 @@ static void MMDevApiClosePlayback(ALCdevice *device)
|
||||
CloseHandle(data->MsgEvent);
|
||||
data->MsgEvent = NULL;
|
||||
|
||||
CloseHandle(data->hNotifyEvent);
|
||||
data->hNotifyEvent = NULL;
|
||||
CloseHandle(data->NotifyEvent);
|
||||
data->NotifyEvent = NULL;
|
||||
|
||||
free(data->devid);
|
||||
data->devid = NULL;
|
||||
@@ -934,6 +941,14 @@ static void MMDevApiStopPlayback(ALCdevice *device)
|
||||
}
|
||||
|
||||
|
||||
static ALint64 MMDevApiGetLatency(ALCdevice *device)
|
||||
{
|
||||
MMDevApiData *data = device->ExtraData;
|
||||
|
||||
return (ALint64)data->Padding * 1000000000 / device->Frequency;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs MMDevApiFuncs = {
|
||||
MMDevApiOpenPlayback,
|
||||
MMDevApiClosePlayback,
|
||||
@@ -945,7 +960,10 @@ static const BackendFuncs MMDevApiFuncs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
MMDevApiGetLatency
|
||||
};
|
||||
|
||||
|
||||
@@ -1007,7 +1025,7 @@ void alcMMDevApiProbe(enum DevProbe type)
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
{
|
||||
if(PlaybackDeviceList[i].name)
|
||||
AppendAllDeviceList(PlaybackDeviceList[i].name);
|
||||
AppendAllDevicesList(PlaybackDeviceList[i].name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+11
-5
@@ -21,9 +21,12 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -84,7 +87,7 @@ static ALCenum null_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
|
||||
data = (null_data*)calloc(1, sizeof(*data));
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -140,7 +143,10 @@ static const BackendFuncs null_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_null_init(BackendFuncs *func_list)
|
||||
@@ -158,7 +164,7 @@ void alc_null_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(nullDevice);
|
||||
AppendAllDevicesList(nullDevice);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
#include <SLES/OpenSLES.h>
|
||||
@@ -231,7 +231,7 @@ static ALCenum opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
Device->szDeviceName = strdup(deviceName);
|
||||
Device->DeviceName = strdup(deviceName);
|
||||
Device->ExtraData = data;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
@@ -412,7 +412,10 @@ static const BackendFuncs opensl_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
|
||||
@@ -431,7 +434,7 @@ void alc_opensl_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(opensl_device);
|
||||
AppendAllDevicesList(opensl_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
|
||||
+32
-25
@@ -30,9 +30,9 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
@@ -79,21 +79,21 @@ static int log2i(ALCuint x)
|
||||
|
||||
static ALuint OSSProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
ALint frameSize;
|
||||
ssize_t wrote;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow && pDevice->Connected)
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
aluMixData(pDevice, WritePtr, len/frameSize);
|
||||
aluMixData(Device, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
@@ -102,7 +102,9 @@ static ALuint OSSProc(ALvoid *ptr)
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
{
|
||||
ERR("write failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -120,14 +122,14 @@ static ALuint OSSProc(ALvoid *ptr)
|
||||
|
||||
static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
int frameSize;
|
||||
int amt;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow)
|
||||
{
|
||||
@@ -135,7 +137,9 @@ static ALuint OSSCaptureProc(ALvoid *ptr)
|
||||
if(amt < 0)
|
||||
{
|
||||
ERR("read failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
if(amt == 0)
|
||||
@@ -170,7 +174,7 @@ static ALCenum oss_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -431,7 +435,7 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -450,28 +454,28 @@ static void oss_close_capture(ALCdevice *device)
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void oss_start_capture(ALCdevice *pDevice)
|
||||
static void oss_start_capture(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
data->doCapture = 1;
|
||||
}
|
||||
|
||||
static void oss_stop_capture(ALCdevice *pDevice)
|
||||
static void oss_stop_capture(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
data->doCapture = 0;
|
||||
}
|
||||
|
||||
static ALCenum oss_capture_samples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
static ALCenum oss_capture_samples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
ReadRingBuffer(data->ring, pBuffer, lSamples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint oss_available_samples(ALCdevice *pDevice)
|
||||
static ALCuint oss_available_samples(ALCdevice *Device)
|
||||
{
|
||||
oss_data *data = (oss_data*)pDevice->ExtraData;
|
||||
oss_data *data = (oss_data*)Device->ExtraData;
|
||||
return RingBufferSize(data->ring);
|
||||
}
|
||||
|
||||
@@ -487,7 +491,10 @@ static const BackendFuncs oss_funcs = {
|
||||
oss_start_capture,
|
||||
oss_stop_capture,
|
||||
oss_capture_samples,
|
||||
oss_available_samples
|
||||
oss_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_oss_init(BackendFuncs *func_list)
|
||||
@@ -511,9 +518,9 @@ void alc_oss_probe(enum DevProbe type)
|
||||
{
|
||||
#ifdef HAVE_STAT
|
||||
struct stat buf;
|
||||
if(stat(oss_device, &buf) == 0)
|
||||
if(stat(oss_driver, &buf) == 0)
|
||||
#endif
|
||||
AppendAllDeviceList(oss_device);
|
||||
AppendAllDevicesList(oss_device);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <portaudio.h>
|
||||
|
||||
@@ -219,7 +219,7 @@ retry_open:
|
||||
}
|
||||
|
||||
device->ExtraData = data;
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -361,7 +361,7 @@ static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
|
||||
goto error;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
@@ -430,7 +430,10 @@ static const BackendFuncs pa_funcs = {
|
||||
pa_start_capture,
|
||||
pa_stop_capture,
|
||||
pa_capture_samples,
|
||||
pa_available_samples
|
||||
pa_available_samples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_pa_init(BackendFuncs *func_list)
|
||||
@@ -460,7 +463,7 @@ void alc_pa_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(pa_device);
|
||||
AppendAllDevicesList(pa_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
AppendCaptureDeviceList(pa_device);
|
||||
|
||||
+106
-46
@@ -21,7 +21,10 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
@@ -65,6 +68,7 @@ MAKE_FUNC(pa_stream_is_corked);
|
||||
MAKE_FUNC(pa_stream_cork);
|
||||
MAKE_FUNC(pa_stream_is_suspended);
|
||||
MAKE_FUNC(pa_stream_get_device_name);
|
||||
MAKE_FUNC(pa_stream_get_latency);
|
||||
MAKE_FUNC(pa_path_get_filename);
|
||||
MAKE_FUNC(pa_get_binary_name);
|
||||
MAKE_FUNC(pa_threaded_mainloop_free);
|
||||
@@ -137,6 +141,7 @@ MAKE_FUNC(pa_stream_begin_write);
|
||||
#define pa_stream_cork ppa_stream_cork
|
||||
#define pa_stream_is_suspended ppa_stream_is_suspended
|
||||
#define pa_stream_get_device_name ppa_stream_get_device_name
|
||||
#define pa_stream_get_latency ppa_stream_get_latency
|
||||
#define pa_path_get_filename ppa_path_get_filename
|
||||
#define pa_get_binary_name ppa_get_binary_name
|
||||
#define pa_threaded_mainloop_free ppa_threaded_mainloop_free
|
||||
@@ -272,6 +277,7 @@ static ALCboolean pulse_load(void)
|
||||
LOAD_FUNC(pa_stream_cork);
|
||||
LOAD_FUNC(pa_stream_is_suspended);
|
||||
LOAD_FUNC(pa_stream_get_device_name);
|
||||
LOAD_FUNC(pa_stream_get_latency);
|
||||
LOAD_FUNC(pa_path_get_filename);
|
||||
LOAD_FUNC(pa_get_binary_name);
|
||||
LOAD_FUNC(pa_threaded_mainloop_free);
|
||||
@@ -525,8 +531,8 @@ static void sink_name_callback(pa_context *context, const pa_sink_info *info, in
|
||||
return;
|
||||
}
|
||||
|
||||
free(device->szDeviceName);
|
||||
device->szDeviceName = strdup(info->description);
|
||||
free(device->DeviceName);
|
||||
device->DeviceName = strdup(info->description);
|
||||
}
|
||||
|
||||
static void source_name_callback(pa_context *context, const pa_source_info *info, int eol, void *pdata)
|
||||
@@ -541,8 +547,21 @@ static void source_name_callback(pa_context *context, const pa_source_info *info
|
||||
return;
|
||||
}
|
||||
|
||||
free(device->szDeviceName);
|
||||
device->szDeviceName = strdup(info->description);
|
||||
free(device->DeviceName);
|
||||
device->DeviceName = strdup(info->description);
|
||||
}
|
||||
|
||||
|
||||
static void stream_moved_callback(pa_stream *stream, void *pdata)
|
||||
{
|
||||
ALCdevice *device = pdata;
|
||||
pulse_data *data = device->ExtraData;
|
||||
(void)stream;
|
||||
|
||||
free(data->device_name);
|
||||
data->device_name = strdup(pa_stream_get_device_name(data->stream));
|
||||
|
||||
TRACE("Stream moved to %s\n", data->device_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -674,14 +693,15 @@ static pa_stream *connect_record_stream(const char *device_name,
|
||||
}
|
||||
|
||||
|
||||
#define WAIT_FOR_OPERATION(x, l) do { \
|
||||
pa_threaded_mainloop *_l = (l); \
|
||||
pa_operation *_o = (x); \
|
||||
if(!_o) break; \
|
||||
while(pa_operation_get_state(_o) == PA_OPERATION_RUNNING) \
|
||||
pa_threaded_mainloop_wait(_l); \
|
||||
pa_operation_unref(_o); \
|
||||
} while(0)
|
||||
static void wait_for_operation(pa_operation *op, pa_threaded_mainloop *loop)
|
||||
{
|
||||
if(op)
|
||||
{
|
||||
while(pa_operation_get_state(op) == PA_OPERATION_RUNNING)
|
||||
pa_threaded_mainloop_wait(loop);
|
||||
pa_operation_unref(op);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void probe_devices(ALboolean capture)
|
||||
@@ -722,7 +742,7 @@ static void probe_devices(ALboolean capture)
|
||||
if(stream)
|
||||
{
|
||||
o = pa_context_get_sink_info_by_name(context, pa_stream_get_device_name(stream), sink_device_callback, loop);
|
||||
WAIT_FOR_OPERATION(o, loop);
|
||||
wait_for_operation(o, loop);
|
||||
|
||||
pa_stream_disconnect(stream);
|
||||
pa_stream_unref(stream);
|
||||
@@ -749,7 +769,7 @@ static void probe_devices(ALboolean capture)
|
||||
if(stream)
|
||||
{
|
||||
o = pa_context_get_source_info_by_name(context, pa_stream_get_device_name(stream), source_device_callback, loop);
|
||||
WAIT_FOR_OPERATION(o, loop);
|
||||
wait_for_operation(o, loop);
|
||||
|
||||
pa_stream_disconnect(stream);
|
||||
pa_stream_unref(stream);
|
||||
@@ -758,7 +778,7 @@ static void probe_devices(ALboolean capture)
|
||||
|
||||
o = pa_context_get_source_info_list(context, source_device_callback, loop);
|
||||
}
|
||||
WAIT_FOR_OPERATION(o, loop);
|
||||
wait_for_operation(o, loop);
|
||||
|
||||
pa_context_disconnect(context);
|
||||
pa_context_unref(context);
|
||||
@@ -822,11 +842,9 @@ static ALuint PulseProc(ALvoid *param)
|
||||
buf = pa_xmalloc(newlen);
|
||||
free_func = pa_xfree;
|
||||
}
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
aluMixData(Device, buf, newlen/frame_size);
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
pa_stream_write(data->stream, buf, newlen, free_func, 0, PA_SEEK_RELATIVE);
|
||||
len -= newlen;
|
||||
}
|
||||
@@ -887,6 +905,7 @@ static void pulse_close(ALCdevice *device)
|
||||
|
||||
if(data->stream)
|
||||
{
|
||||
pa_stream_set_moved_callback(data->stream, NULL, NULL);
|
||||
#if PA_CHECK_VERSION(0,9,15)
|
||||
if(pa_stream_set_buffer_attr_callback)
|
||||
pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL);
|
||||
@@ -944,7 +963,9 @@ static ALCenum pulse_open_playback(ALCdevice *device, const ALCchar *device_name
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
flags = PA_STREAM_FIX_FORMAT | PA_STREAM_FIX_RATE |
|
||||
PA_STREAM_FIX_CHANNELS | PA_STREAM_DONT_MOVE;
|
||||
PA_STREAM_FIX_CHANNELS;
|
||||
if(!GetConfigValueBool("pulse", "allow-moves", 0))
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
|
||||
spec.format = PA_SAMPLE_S16NE;
|
||||
spec.rate = 44100;
|
||||
@@ -962,7 +983,9 @@ static ALCenum pulse_open_playback(ALCdevice *device, const ALCchar *device_name
|
||||
data->device_name = strdup(pa_stream_get_device_name(data->stream));
|
||||
o = pa_context_get_sink_info_by_name(data->context, data->device_name,
|
||||
sink_name_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
|
||||
pa_stream_set_moved_callback(data->stream, stream_moved_callback, device);
|
||||
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
@@ -979,11 +1002,13 @@ static ALCboolean pulse_reset_playback(ALCdevice *device)
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_stream_flags_t flags = 0;
|
||||
pa_channel_map chanmap;
|
||||
ALuint len;
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
if(data->stream)
|
||||
{
|
||||
pa_stream_set_moved_callback(data->stream, NULL, NULL);
|
||||
#if PA_CHECK_VERSION(0,9,15)
|
||||
if(pa_stream_set_buffer_attr_callback)
|
||||
pa_stream_set_buffer_attr_callback(data->stream, NULL, NULL);
|
||||
@@ -997,7 +1022,7 @@ static ALCboolean pulse_reset_playback(ALCdevice *device)
|
||||
{
|
||||
pa_operation *o;
|
||||
o = pa_context_get_sink_info_by_name(data->context, data->device_name, sink_info_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
}
|
||||
if(!(device->Flags&DEVICE_FREQUENCY_REQUEST))
|
||||
flags |= PA_STREAM_FIX_RATE;
|
||||
@@ -1005,7 +1030,8 @@ static ALCboolean pulse_reset_playback(ALCdevice *device)
|
||||
flags |= PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE;
|
||||
flags |= PA_STREAM_ADJUST_LATENCY;
|
||||
flags |= PA_STREAM_START_CORKED;
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
if(!GetConfigValueBool("pulse", "allow-moves", 0))
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
|
||||
switch(device->FmtType)
|
||||
{
|
||||
@@ -1072,28 +1098,33 @@ static ALCboolean pulse_reset_playback(ALCdevice *device)
|
||||
|
||||
/* Server updated our playback rate, so modify the buffer attribs
|
||||
* accordingly. */
|
||||
data->attr.minreq = (ALuint64)device->UpdateSize * data->spec.rate /
|
||||
device->Frequency * pa_frame_size(&data->spec);
|
||||
data->attr.tlength = data->attr.minreq * maxu(device->NumUpdates, 2);
|
||||
data->attr.prebuf = 0;
|
||||
device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates / device->Frequency *
|
||||
data->spec.rate + 0.5);
|
||||
data->attr.minreq = device->UpdateSize * pa_frame_size(&data->spec);
|
||||
data->attr.tlength = data->attr.minreq * clampu(device->NumUpdates, 2, 16);
|
||||
data->attr.maxlength = -1;
|
||||
data->attr.prebuf = 0;
|
||||
|
||||
o = pa_stream_set_buffer_attr(data->stream, &data->attr,
|
||||
stream_success_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
|
||||
device->Frequency = data->spec.rate;
|
||||
}
|
||||
|
||||
pa_stream_set_moved_callback(data->stream, stream_moved_callback, device);
|
||||
#if PA_CHECK_VERSION(0,9,15)
|
||||
if(pa_stream_set_buffer_attr_callback)
|
||||
pa_stream_set_buffer_attr_callback(data->stream, stream_buffer_attr_callback, device);
|
||||
#endif
|
||||
stream_buffer_attr_callback(data->stream, device);
|
||||
|
||||
device->NumUpdates = device->UpdateSize*device->NumUpdates /
|
||||
(data->attr.minreq/pa_frame_size(&data->spec));
|
||||
device->NumUpdates = maxu(device->NumUpdates, 2);
|
||||
device->UpdateSize = data->attr.minreq / pa_frame_size(&data->spec);
|
||||
len = data->attr.minreq / pa_frame_size(&data->spec);
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
len = (len+3)&~3;
|
||||
device->NumUpdates = (ALuint)((ALdouble)device->NumUpdates/len*device->UpdateSize + 0.5);
|
||||
device->NumUpdates = clampu(device->NumUpdates, 2, 16);
|
||||
device->UpdateSize = len;
|
||||
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_TRUE;
|
||||
@@ -1129,7 +1160,7 @@ static void pulse_stop_playback(ALCdevice *device)
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
|
||||
o = pa_stream_cork(data->stream, 1, stream_success_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
}
|
||||
@@ -1218,8 +1249,10 @@ static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name)
|
||||
data->attr.fragsize = minu(samples, 50*device->Frequency/1000) *
|
||||
pa_frame_size(&data->spec);
|
||||
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
flags |= PA_STREAM_START_CORKED|PA_STREAM_ADJUST_LATENCY;
|
||||
if(!GetConfigValueBool("pulse", "allow-moves", 0))
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
|
||||
data->stream = connect_record_stream(pulse_name, data->loop, data->context,
|
||||
flags, &data->attr, &data->spec,
|
||||
&chanmap);
|
||||
@@ -1233,7 +1266,9 @@ static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name)
|
||||
data->device_name = strdup(pa_stream_get_device_name(data->stream));
|
||||
o = pa_context_get_source_info_by_name(data->context, data->device_name,
|
||||
source_name_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
|
||||
pa_stream_set_moved_callback(data->stream, stream_moved_callback, device);
|
||||
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
return ALC_NO_ERROR;
|
||||
@@ -1253,10 +1288,8 @@ static void pulse_start_capture(ALCdevice *device)
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_operation *o;
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
o = pa_stream_cork(data->stream, 0, stream_success_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
}
|
||||
|
||||
static void pulse_stop_capture(ALCdevice *device)
|
||||
@@ -1264,10 +1297,8 @@ static void pulse_stop_capture(ALCdevice *device)
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_operation *o;
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
o = pa_stream_cork(data->stream, 1, stream_success_callback, device);
|
||||
WAIT_FOR_OPERATION(o, data->loop);
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
wait_for_operation(o, data->loop);
|
||||
}
|
||||
|
||||
static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples)
|
||||
@@ -1275,7 +1306,6 @@ static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint
|
||||
pulse_data *data = device->ExtraData;
|
||||
ALCuint todo = samples * pa_frame_size(&data->spec);
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
/* Capture is done in fragment-sized chunks, so we loop until we get all
|
||||
* that's available */
|
||||
data->last_readable -= todo;
|
||||
@@ -1320,7 +1350,6 @@ static ALCenum pulse_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint
|
||||
}
|
||||
if(todo > 0)
|
||||
memset(buffer, ((device->FmtType==DevFmtUByte) ? 0x80 : 0), todo);
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -1330,7 +1359,6 @@ static ALCuint pulse_available_samples(ALCdevice *device)
|
||||
pulse_data *data = device->ExtraData;
|
||||
size_t readable = data->cap_remain;
|
||||
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
if(device->Connected)
|
||||
{
|
||||
ssize_t got = pa_stream_readable_size(data->stream);
|
||||
@@ -1342,7 +1370,6 @@ static ALCuint pulse_available_samples(ALCdevice *device)
|
||||
else if((size_t)got > data->cap_len)
|
||||
readable += got - data->cap_len;
|
||||
}
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
|
||||
if(data->last_readable < readable)
|
||||
data->last_readable = readable;
|
||||
@@ -1350,6 +1377,36 @@ static ALCuint pulse_available_samples(ALCdevice *device)
|
||||
}
|
||||
|
||||
|
||||
static void pulse_lock(ALCdevice *device)
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_threaded_mainloop_lock(data->loop);
|
||||
}
|
||||
|
||||
static void pulse_unlock(ALCdevice *device)
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_threaded_mainloop_unlock(data->loop);
|
||||
}
|
||||
|
||||
|
||||
static ALint64 pulse_get_latency(ALCdevice *device)
|
||||
{
|
||||
pulse_data *data = device->ExtraData;
|
||||
pa_usec_t latency = 0;
|
||||
int neg;
|
||||
|
||||
if(pa_stream_get_latency(data->stream, &latency, &neg) == 0)
|
||||
{
|
||||
if(neg)
|
||||
latency = 0;
|
||||
return (ALint64)minu64(latency, MAKEU64(0x7fffffff,0xffffffff)/1000) * 1000;
|
||||
}
|
||||
ERR("Failed to get stream latency!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const BackendFuncs pulse_funcs = {
|
||||
pulse_open_playback,
|
||||
pulse_close_playback,
|
||||
@@ -1361,7 +1418,10 @@ static const BackendFuncs pulse_funcs = {
|
||||
pulse_start_capture,
|
||||
pulse_stop_capture,
|
||||
pulse_capture_samples,
|
||||
pulse_available_samples
|
||||
pulse_available_samples,
|
||||
pulse_lock,
|
||||
pulse_unlock,
|
||||
pulse_get_latency
|
||||
};
|
||||
|
||||
ALCboolean alc_pulse_init(BackendFuncs *func_list)
|
||||
@@ -1373,7 +1433,7 @@ ALCboolean alc_pulse_init(BackendFuncs *func_list)
|
||||
pa_threaded_mainloop *loop;
|
||||
|
||||
pulse_ctx_flags = 0;
|
||||
if(!GetConfigValueBool("pulse", "spawn-server", 0))
|
||||
if(!GetConfigValueBool("pulse", "spawn-server", 1))
|
||||
pulse_ctx_flags |= PA_CONTEXT_NOAUTOSPAWN;
|
||||
|
||||
if((loop=pa_threaded_mainloop_new()) &&
|
||||
@@ -1457,7 +1517,7 @@ void alc_pulse_probe(enum DevProbe type)
|
||||
probe_devices(AL_FALSE);
|
||||
|
||||
for(i = 0;i < numDevNames;i++)
|
||||
AppendAllDeviceList(allDevNameMap[i].name);
|
||||
AppendAllDevicesList(allDevNameMap[i].name);
|
||||
break;
|
||||
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
|
||||
+10
-86
@@ -23,9 +23,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sndio.h>
|
||||
|
||||
@@ -33,84 +33,8 @@
|
||||
static const ALCchar sndio_device[] = "SndIO Default";
|
||||
|
||||
|
||||
#ifdef HAVE_DYNLOAD
|
||||
static void *sndio_handle;
|
||||
#define MAKE_FUNC(x) static typeof(x) * p##x
|
||||
MAKE_FUNC(sio_initpar);
|
||||
MAKE_FUNC(sio_open);
|
||||
MAKE_FUNC(sio_close);
|
||||
MAKE_FUNC(sio_setpar);
|
||||
MAKE_FUNC(sio_getpar);
|
||||
MAKE_FUNC(sio_getcap);
|
||||
MAKE_FUNC(sio_onmove);
|
||||
MAKE_FUNC(sio_write);
|
||||
MAKE_FUNC(sio_read);
|
||||
MAKE_FUNC(sio_start);
|
||||
MAKE_FUNC(sio_stop);
|
||||
MAKE_FUNC(sio_nfds);
|
||||
MAKE_FUNC(sio_pollfd);
|
||||
MAKE_FUNC(sio_revents);
|
||||
MAKE_FUNC(sio_eof);
|
||||
MAKE_FUNC(sio_setvol);
|
||||
MAKE_FUNC(sio_onvol);
|
||||
|
||||
#define sio_initpar psio_initpar
|
||||
#define sio_open psio_open
|
||||
#define sio_close psio_close
|
||||
#define sio_setpar psio_setpar
|
||||
#define sio_getpar psio_getpar
|
||||
#define sio_getcap psio_getcap
|
||||
#define sio_onmove psio_onmove
|
||||
#define sio_write psio_write
|
||||
#define sio_read psio_read
|
||||
#define sio_start psio_start
|
||||
#define sio_stop psio_stop
|
||||
#define sio_nfds psio_nfds
|
||||
#define sio_pollfd psio_pollfd
|
||||
#define sio_revents psio_revents
|
||||
#define sio_eof psio_eof
|
||||
#define sio_setvol psio_setvol
|
||||
#define sio_onvol psio_onvol
|
||||
#endif
|
||||
|
||||
|
||||
static ALCboolean sndio_load(void)
|
||||
{
|
||||
#ifdef HAVE_DYNLOAD
|
||||
if(!sndio_handle)
|
||||
{
|
||||
sndio_handle = LoadLib("libsndio.so");
|
||||
if(!sndio_handle)
|
||||
return ALC_FALSE;
|
||||
|
||||
#define LOAD_FUNC(f) do { \
|
||||
p##f = GetSymbol(sndio_handle, #f); \
|
||||
if(p##f == NULL) { \
|
||||
CloseLib(sndio_handle); \
|
||||
sndio_handle = NULL; \
|
||||
return ALC_FALSE; \
|
||||
} \
|
||||
} while(0)
|
||||
LOAD_FUNC(sio_initpar);
|
||||
LOAD_FUNC(sio_open);
|
||||
LOAD_FUNC(sio_close);
|
||||
LOAD_FUNC(sio_setpar);
|
||||
LOAD_FUNC(sio_getpar);
|
||||
LOAD_FUNC(sio_getcap);
|
||||
LOAD_FUNC(sio_onmove);
|
||||
LOAD_FUNC(sio_write);
|
||||
LOAD_FUNC(sio_read);
|
||||
LOAD_FUNC(sio_start);
|
||||
LOAD_FUNC(sio_stop);
|
||||
LOAD_FUNC(sio_nfds);
|
||||
LOAD_FUNC(sio_pollfd);
|
||||
LOAD_FUNC(sio_revents);
|
||||
LOAD_FUNC(sio_eof);
|
||||
LOAD_FUNC(sio_setvol);
|
||||
LOAD_FUNC(sio_onvol);
|
||||
#undef LOAD_FUNC
|
||||
}
|
||||
#endif
|
||||
return ALC_TRUE;
|
||||
}
|
||||
|
||||
@@ -149,7 +73,9 @@ static ALuint sndio_proc(ALvoid *ptr)
|
||||
if(wrote == 0)
|
||||
{
|
||||
ERR("sio_write failed\n");
|
||||
ALCdevice_Lock(device);
|
||||
aluHandleDisconnect(device);
|
||||
ALCdevice_Unlock(device);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -183,7 +109,7 @@ static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
|
||||
return ALC_NO_ERROR;
|
||||
@@ -339,7 +265,10 @@ static const BackendFuncs sndio_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_sndio_init(BackendFuncs *func_list)
|
||||
@@ -352,11 +281,6 @@ ALCboolean alc_sndio_init(BackendFuncs *func_list)
|
||||
|
||||
void alc_sndio_deinit(void)
|
||||
{
|
||||
#ifdef HAVE_DYNLOAD
|
||||
if(sndio_handle)
|
||||
CloseLib(sndio_handle);
|
||||
sndio_handle = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void alc_sndio_probe(enum DevProbe type)
|
||||
@@ -364,7 +288,7 @@ void alc_sndio_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(sndio_device);
|
||||
AppendAllDevicesList(sndio_device);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
|
||||
+16
-11
@@ -30,9 +30,9 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include <sys/audioio.h>
|
||||
|
||||
@@ -53,21 +53,21 @@ typedef struct {
|
||||
|
||||
static ALuint SolarisProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
solaris_data *data = (solaris_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
solaris_data *data = (solaris_data*)Device->ExtraData;
|
||||
ALint frameSize;
|
||||
int wrote;
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(!data->killNow && pDevice->Connected)
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
ALint len = data->data_size;
|
||||
ALubyte *WritePtr = data->mix_data;
|
||||
|
||||
aluMixData(pDevice, WritePtr, len/frameSize);
|
||||
aluMixData(Device, WritePtr, len/frameSize);
|
||||
while(len > 0 && !data->killNow)
|
||||
{
|
||||
wrote = write(data->fd, WritePtr, len);
|
||||
@@ -76,7 +76,9 @@ static ALuint SolarisProc(ALvoid *ptr)
|
||||
if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
{
|
||||
ERR("write failed: %s\n", strerror(errno));
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -113,7 +115,7 @@ static ALCenum solaris_open_playback(ALCdevice *device, const ALCchar *deviceNam
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -247,7 +249,10 @@ static const BackendFuncs solaris_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_solaris_init(BackendFuncs *func_list)
|
||||
@@ -272,7 +277,7 @@ void alc_solaris_probe(enum DevProbe type)
|
||||
struct stat buf;
|
||||
if(stat(solaris_driver, &buf) == 0)
|
||||
#endif
|
||||
AppendAllDeviceList(solaris_device);
|
||||
AppendAllDevicesList(solaris_device);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+32
-20
@@ -23,9 +23,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -81,45 +84,45 @@ static void fwrite32le(ALuint val, FILE *f)
|
||||
|
||||
static ALuint WaveProc(ALvoid *ptr)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)ptr;
|
||||
wave_data *data = (wave_data*)pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)ptr;
|
||||
wave_data *data = (wave_data*)Device->ExtraData;
|
||||
ALuint frameSize;
|
||||
ALuint now, start;
|
||||
ALuint64 avail, done;
|
||||
size_t fs;
|
||||
const ALuint restTime = (ALuint64)pDevice->UpdateSize * 1000 /
|
||||
pDevice->Frequency / 2;
|
||||
const ALuint restTime = (ALuint64)Device->UpdateSize * 1000 /
|
||||
Device->Frequency / 2;
|
||||
|
||||
frameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
done = 0;
|
||||
start = timeGetTime();
|
||||
while(!data->killNow && pDevice->Connected)
|
||||
while(!data->killNow && Device->Connected)
|
||||
{
|
||||
now = timeGetTime();
|
||||
|
||||
avail = (ALuint64)(now-start) * pDevice->Frequency / 1000;
|
||||
avail = (ALuint64)(now-start) * Device->Frequency / 1000;
|
||||
if(avail < done)
|
||||
{
|
||||
/* Timer wrapped (50 days???). Add the remainder of the cycle to
|
||||
* the available count and reset the number of samples done */
|
||||
avail += ((ALuint64)1<<32)*pDevice->Frequency/1000 - done;
|
||||
avail += ((ALuint64)1<<32)*Device->Frequency/1000 - done;
|
||||
done = 0;
|
||||
}
|
||||
if(avail-done < pDevice->UpdateSize)
|
||||
if(avail-done < Device->UpdateSize)
|
||||
{
|
||||
Sleep(restTime);
|
||||
continue;
|
||||
}
|
||||
|
||||
while(avail-done >= pDevice->UpdateSize)
|
||||
while(avail-done >= Device->UpdateSize)
|
||||
{
|
||||
aluMixData(pDevice, data->buffer, pDevice->UpdateSize);
|
||||
done += pDevice->UpdateSize;
|
||||
aluMixData(Device, data->buffer, Device->UpdateSize);
|
||||
done += Device->UpdateSize;
|
||||
|
||||
if(!IS_LITTLE_ENDIAN)
|
||||
{
|
||||
ALuint bytesize = BytesFromDevFmt(pDevice->FmtType);
|
||||
ALuint bytesize = BytesFromDevFmt(Device->FmtType);
|
||||
ALubyte *bytes = data->buffer;
|
||||
ALuint i;
|
||||
|
||||
@@ -140,12 +143,17 @@ static ALuint WaveProc(ALvoid *ptr)
|
||||
}
|
||||
}
|
||||
else
|
||||
fs = fwrite(data->buffer, frameSize, pDevice->UpdateSize,
|
||||
{
|
||||
fs = fwrite(data->buffer, frameSize, Device->UpdateSize,
|
||||
data->f);
|
||||
fs = fs;
|
||||
}
|
||||
if(ferror(data->f))
|
||||
{
|
||||
ERR("Error writing to file\n");
|
||||
aluHandleDisconnect(pDevice);
|
||||
ALCdevice_Lock(Device);
|
||||
aluHandleDisconnect(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +186,7 @@ static ALCenum wave_open_playback(ALCdevice *device, const ALCchar *deviceName)
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
device->szDeviceName = strdup(deviceName);
|
||||
device->DeviceName = strdup(deviceName);
|
||||
device->ExtraData = data;
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
@@ -249,6 +257,7 @@ static ALCboolean wave_reset_playback(ALCdevice *device)
|
||||
fwrite32le(channel_masks[channels], data->f);
|
||||
// 16 byte GUID, sub-type format
|
||||
val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f);
|
||||
val = val;
|
||||
|
||||
fprintf(data->f, "data");
|
||||
fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close
|
||||
@@ -329,7 +338,10 @@ static const BackendFuncs wave_funcs = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alc_wave_init(BackendFuncs *func_list)
|
||||
@@ -350,7 +362,7 @@ void alc_wave_probe(enum DevProbe type)
|
||||
switch(type)
|
||||
{
|
||||
case ALL_DEVICE_PROBE:
|
||||
AppendAllDeviceList(waveDevice);
|
||||
AppendAllDevicesList(waveDevice);
|
||||
break;
|
||||
case CAPTURE_DEVICE_PROBE:
|
||||
break;
|
||||
|
||||
+228
-231
@@ -28,8 +28,7 @@
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
|
||||
@@ -38,21 +37,21 @@
|
||||
|
||||
typedef struct {
|
||||
// MMSYSTEM Device
|
||||
volatile ALboolean bWaveShutdown;
|
||||
HANDLE hWaveThreadEvent;
|
||||
HANDLE hWaveThread;
|
||||
DWORD ulWaveThreadID;
|
||||
volatile LONG lWaveBuffersCommitted;
|
||||
volatile ALboolean killNow;
|
||||
HANDLE WaveThreadEvent;
|
||||
HANDLE WaveThread;
|
||||
DWORD WaveThreadID;
|
||||
volatile LONG WaveBuffersCommitted;
|
||||
WAVEHDR WaveBuffer[4];
|
||||
|
||||
union {
|
||||
HWAVEIN In;
|
||||
HWAVEOUT Out;
|
||||
} hWaveHandle;
|
||||
} WaveHandle;
|
||||
|
||||
WAVEFORMATEX wfexFormat;
|
||||
WAVEFORMATEX Format;
|
||||
|
||||
RingBuffer *pRing;
|
||||
RingBuffer *Ring;
|
||||
} WinMMData;
|
||||
|
||||
|
||||
@@ -147,19 +146,19 @@ static void ProbeCaptureDevices(void)
|
||||
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)
|
||||
static void CALLBACK WaveOutProc(HWAVEOUT device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)dwInstance;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)instance;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
|
||||
(void)hDevice;
|
||||
(void)dwParam2;
|
||||
(void)device;
|
||||
(void)param2;
|
||||
|
||||
if(uMsg != WOM_DONE)
|
||||
if(msg != WOM_DONE)
|
||||
return;
|
||||
|
||||
InterlockedDecrement(&pData->lWaveBuffersCommitted);
|
||||
PostThreadMessage(pData->ulWaveThreadID, uMsg, 0, dwParam1);
|
||||
InterlockedDecrement(&data->WaveBuffersCommitted);
|
||||
PostThreadMessage(data->WaveThreadID, msg, 0, param1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -168,15 +167,15 @@ static void CALLBACK WaveOutProc(HWAVEOUT hDevice,UINT uMsg,DWORD_PTR dwInstance
|
||||
Used by "MMSYSTEM" Device. Called when a WaveOut buffer has used up its
|
||||
audio data.
|
||||
*/
|
||||
static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter)
|
||||
static DWORD WINAPI PlaybackThreadProc(LPVOID param)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)lpParameter;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
LPWAVEHDR pWaveHdr;
|
||||
ALCdevice *Device = (ALCdevice*)param;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
LPWAVEHDR WaveHdr;
|
||||
ALuint FrameSize;
|
||||
MSG msg;
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
SetRTPriority();
|
||||
|
||||
@@ -185,28 +184,26 @@ static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter)
|
||||
if(msg.message != WOM_DONE)
|
||||
continue;
|
||||
|
||||
if(pData->bWaveShutdown)
|
||||
if(data->killNow)
|
||||
{
|
||||
if(pData->lWaveBuffersCommitted == 0)
|
||||
if(data->WaveBuffersCommitted == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
pWaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
|
||||
aluMixData(pDevice, pWaveHdr->lpData, pWaveHdr->dwBufferLength/FrameSize);
|
||||
WaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength/FrameSize);
|
||||
|
||||
// Send buffer back to play more data
|
||||
waveOutWrite(pData->hWaveHandle.Out, pWaveHdr, sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&pData->lWaveBuffersCommitted);
|
||||
waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
// Signal Wave Thread completed event
|
||||
if(pData->hWaveThreadEvent)
|
||||
SetEvent(pData->hWaveThreadEvent);
|
||||
if(data->WaveThreadEvent)
|
||||
SetEvent(data->WaveThreadEvent);
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,19 +213,19 @@ static DWORD WINAPI PlaybackThreadProc(LPVOID lpParameter)
|
||||
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)
|
||||
static void CALLBACK WaveInProc(HWAVEIN device, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)dwInstance;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
ALCdevice *Device = (ALCdevice*)instance;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
|
||||
(void)hDevice;
|
||||
(void)dwParam2;
|
||||
(void)device;
|
||||
(void)param2;
|
||||
|
||||
if(uMsg != WIM_DATA)
|
||||
if(msg != WIM_DATA)
|
||||
return;
|
||||
|
||||
InterlockedDecrement(&pData->lWaveBuffersCommitted);
|
||||
PostThreadMessage(pData->ulWaveThreadID,uMsg,0,dwParam1);
|
||||
InterlockedDecrement(&data->WaveBuffersCommitted);
|
||||
PostThreadMessage(data->WaveThreadID, msg, 0, param1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -237,15 +234,15 @@ static void CALLBACK WaveInProc(HWAVEIN hDevice,UINT uMsg,DWORD_PTR dwInstance,D
|
||||
Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new
|
||||
audio data.
|
||||
*/
|
||||
static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter)
|
||||
static DWORD WINAPI CaptureThreadProc(LPVOID param)
|
||||
{
|
||||
ALCdevice *pDevice = (ALCdevice*)lpParameter;
|
||||
WinMMData *pData = pDevice->ExtraData;
|
||||
LPWAVEHDR pWaveHdr;
|
||||
ALCdevice *Device = (ALCdevice*)param;
|
||||
WinMMData *data = Device->ExtraData;
|
||||
LPWAVEHDR WaveHdr;
|
||||
ALuint FrameSize;
|
||||
MSG msg;
|
||||
|
||||
FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType);
|
||||
FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType);
|
||||
|
||||
while(GetMessage(&msg, NULL, 0, 0))
|
||||
{
|
||||
@@ -253,33 +250,30 @@ static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter)
|
||||
continue;
|
||||
/* Don't wait for other buffers to finish before quitting. We're
|
||||
* closing so we don't need them. */
|
||||
if(pData->bWaveShutdown)
|
||||
if(data->killNow)
|
||||
break;
|
||||
|
||||
pWaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
|
||||
WriteRingBuffer(pData->pRing, (ALubyte*)pWaveHdr->lpData,
|
||||
pWaveHdr->dwBytesRecorded/FrameSize);
|
||||
WaveHdr = ((LPWAVEHDR)msg.lParam);
|
||||
WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, WaveHdr->dwBytesRecorded/FrameSize);
|
||||
|
||||
// Send buffer back to capture more data
|
||||
waveInAddBuffer(pData->hWaveHandle.In,pWaveHdr,sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&pData->lWaveBuffersCommitted);
|
||||
waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
// Signal Wave Thread completed event
|
||||
if(pData->hWaveThreadEvent)
|
||||
SetEvent(pData->hWaveThreadEvent);
|
||||
if(data->WaveThreadEvent)
|
||||
SetEvent(data->WaveThreadEvent);
|
||||
|
||||
ExitThread(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ALCenum WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
WinMMData *pData = NULL;
|
||||
UINT lDeviceID = 0;
|
||||
WinMMData *data = NULL;
|
||||
UINT DeviceID = 0;
|
||||
MMRESULT res;
|
||||
ALuint i = 0;
|
||||
|
||||
@@ -292,86 +286,86 @@ static ALCenum WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
if(PlaybackDeviceList[i] &&
|
||||
(!deviceName || strcmp(deviceName, PlaybackDeviceList[i]) == 0))
|
||||
{
|
||||
lDeviceID = i;
|
||||
DeviceID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == NumPlaybackDevices)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
pData = calloc(1, sizeof(*pData));
|
||||
if(!pData)
|
||||
data = calloc(1, sizeof(*data));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
pDevice->ExtraData = pData;
|
||||
Device->ExtraData = data;
|
||||
|
||||
retry_open:
|
||||
memset(&pData->wfexFormat, 0, sizeof(WAVEFORMATEX));
|
||||
if(pDevice->FmtType == DevFmtFloat)
|
||||
memset(&data->Format, 0, sizeof(WAVEFORMATEX));
|
||||
if(Device->FmtType == DevFmtFloat)
|
||||
{
|
||||
pData->wfexFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
pData->wfexFormat.wBitsPerSample = 32;
|
||||
data->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
data->Format.wBitsPerSample = 32;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData->wfexFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||
if(pDevice->FmtType == DevFmtUByte || pDevice->FmtType == DevFmtByte)
|
||||
pData->wfexFormat.wBitsPerSample = 8;
|
||||
data->Format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
if(Device->FmtType == DevFmtUByte || Device->FmtType == DevFmtByte)
|
||||
data->Format.wBitsPerSample = 8;
|
||||
else
|
||||
pData->wfexFormat.wBitsPerSample = 16;
|
||||
data->Format.wBitsPerSample = 16;
|
||||
}
|
||||
pData->wfexFormat.nChannels = ((pDevice->FmtChans == DevFmtMono) ? 1 : 2);
|
||||
pData->wfexFormat.nBlockAlign = pData->wfexFormat.wBitsPerSample *
|
||||
pData->wfexFormat.nChannels / 8;
|
||||
pData->wfexFormat.nSamplesPerSec = pDevice->Frequency;
|
||||
pData->wfexFormat.nAvgBytesPerSec = pData->wfexFormat.nSamplesPerSec *
|
||||
pData->wfexFormat.nBlockAlign;
|
||||
pData->wfexFormat.cbSize = 0;
|
||||
data->Format.nChannels = ((Device->FmtChans == DevFmtMono) ? 1 : 2);
|
||||
data->Format.nBlockAlign = data->Format.wBitsPerSample *
|
||||
data->Format.nChannels / 8;
|
||||
data->Format.nSamplesPerSec = Device->Frequency;
|
||||
data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
|
||||
data->Format.nBlockAlign;
|
||||
data->Format.cbSize = 0;
|
||||
|
||||
if((res=waveOutOpen(&pData->hWaveHandle.Out, lDeviceID, &pData->wfexFormat, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
if((res=waveOutOpen(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
if(pDevice->FmtType == DevFmtFloat)
|
||||
if(Device->FmtType == DevFmtFloat)
|
||||
{
|
||||
pDevice->FmtType = DevFmtShort;
|
||||
Device->FmtType = DevFmtShort;
|
||||
goto retry_open;
|
||||
}
|
||||
ERR("waveOutOpen failed: %u\n", res);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(pData->hWaveThreadEvent == NULL)
|
||||
data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->WaveThreadEvent == NULL)
|
||||
{
|
||||
ERR("CreateEvent failed: %lu\n", GetLastError());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
pDevice->szDeviceName = strdup(PlaybackDeviceList[lDeviceID]);
|
||||
Device->DeviceName = strdup(PlaybackDeviceList[DeviceID]);
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
failure:
|
||||
if(pData->hWaveThreadEvent)
|
||||
CloseHandle(pData->hWaveThreadEvent);
|
||||
if(data->WaveThreadEvent)
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
|
||||
if(pData->hWaveHandle.Out)
|
||||
waveOutClose(pData->hWaveHandle.Out);
|
||||
if(data->WaveHandle.Out)
|
||||
waveOutClose(data->WaveHandle.Out);
|
||||
|
||||
free(pData);
|
||||
pDevice->ExtraData = NULL;
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void WinMMClosePlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)device->ExtraData;
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
|
||||
// Close the Wave device
|
||||
CloseHandle(pData->hWaveThreadEvent);
|
||||
pData->hWaveThreadEvent = 0;
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
data->WaveThreadEvent = 0;
|
||||
|
||||
waveOutClose(pData->hWaveHandle.Out);
|
||||
pData->hWaveHandle.Out = 0;
|
||||
waveOutClose(data->WaveHandle.Out);
|
||||
data->WaveHandle.Out = 0;
|
||||
|
||||
free(pData);
|
||||
free(data);
|
||||
device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
@@ -380,47 +374,47 @@ static ALCboolean WinMMResetPlayback(ALCdevice *device)
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
|
||||
device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize *
|
||||
data->wfexFormat.nSamplesPerSec /
|
||||
data->Format.nSamplesPerSec /
|
||||
device->Frequency);
|
||||
device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4;
|
||||
device->NumUpdates = 4;
|
||||
device->Frequency = data->wfexFormat.nSamplesPerSec;
|
||||
device->Frequency = data->Format.nSamplesPerSec;
|
||||
|
||||
if(data->wfexFormat.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||||
if(data->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
|
||||
{
|
||||
if(data->wfexFormat.wBitsPerSample == 32)
|
||||
if(data->Format.wBitsPerSample == 32)
|
||||
device->FmtType = DevFmtFloat;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled IEEE float sample depth: %d\n", data->wfexFormat.wBitsPerSample);
|
||||
ERR("Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
else if(data->wfexFormat.wFormatTag == WAVE_FORMAT_PCM)
|
||||
else if(data->Format.wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
if(data->wfexFormat.wBitsPerSample == 16)
|
||||
if(data->Format.wBitsPerSample == 16)
|
||||
device->FmtType = DevFmtShort;
|
||||
else if(data->wfexFormat.wBitsPerSample == 8)
|
||||
else if(data->Format.wBitsPerSample == 8)
|
||||
device->FmtType = DevFmtUByte;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled PCM sample depth: %d\n", data->wfexFormat.wBitsPerSample);
|
||||
ERR("Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("Unhandled format tag: 0x%04x\n", data->wfexFormat.wFormatTag);
|
||||
ERR("Unhandled format tag: 0x%04x\n", data->Format.wFormatTag);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
|
||||
if(data->wfexFormat.nChannels == 2)
|
||||
if(data->Format.nChannels == 2)
|
||||
device->FmtChans = DevFmtStereo;
|
||||
else if(data->wfexFormat.nChannels == 1)
|
||||
else if(data->Format.nChannels == 1)
|
||||
device->FmtChans = DevFmtMono;
|
||||
else
|
||||
{
|
||||
ERR("Unhandled channel count: %d\n", data->wfexFormat.nChannels);
|
||||
ERR("Unhandled channel count: %d\n", data->Format.nChannels);
|
||||
return ALC_FALSE;
|
||||
}
|
||||
SetDefaultWFXChannelOrder(device);
|
||||
@@ -430,32 +424,32 @@ static ALCboolean WinMMResetPlayback(ALCdevice *device)
|
||||
|
||||
static ALCboolean WinMMStartPlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)device->ExtraData;
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
ALbyte *BufferData;
|
||||
ALint lBufferSize;
|
||||
ALint BufferSize;
|
||||
ALuint i;
|
||||
|
||||
pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &pData->ulWaveThreadID);
|
||||
if(pData->hWaveThread == NULL)
|
||||
data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PlaybackThreadProc, (LPVOID)device, 0, &data->WaveThreadID);
|
||||
if(data->WaveThread == NULL)
|
||||
return ALC_FALSE;
|
||||
|
||||
pData->lWaveBuffersCommitted = 0;
|
||||
data->WaveBuffersCommitted = 0;
|
||||
|
||||
// Create 4 Buffers
|
||||
lBufferSize = device->UpdateSize*device->NumUpdates / 4;
|
||||
lBufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
BufferSize = device->UpdateSize*device->NumUpdates / 4;
|
||||
BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType);
|
||||
|
||||
BufferData = calloc(4, lBufferSize);
|
||||
BufferData = calloc(4, BufferSize);
|
||||
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);
|
||||
memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
|
||||
data->WaveBuffer[i].dwBufferLength = BufferSize;
|
||||
data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
|
||||
(data->WaveBuffer[i-1].lpData +
|
||||
data->WaveBuffer[i-1].dwBufferLength));
|
||||
waveOutPrepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
waveOutWrite(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
return ALC_TRUE;
|
||||
@@ -463,42 +457,42 @@ static ALCboolean WinMMStartPlayback(ALCdevice *device)
|
||||
|
||||
static void WinMMStopPlayback(ALCdevice *device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)device->ExtraData;
|
||||
WinMMData *data = (WinMMData*)device->ExtraData;
|
||||
void *buffer = NULL;
|
||||
int i;
|
||||
|
||||
if(pData->hWaveThread == NULL)
|
||||
if(data->WaveThread == NULL)
|
||||
return;
|
||||
|
||||
// Set flag to stop processing headers
|
||||
pData->bWaveShutdown = AL_TRUE;
|
||||
data->killNow = AL_TRUE;
|
||||
|
||||
// Wait for signal that Wave Thread has been destroyed
|
||||
WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE);
|
||||
WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
|
||||
|
||||
CloseHandle(pData->hWaveThread);
|
||||
pData->hWaveThread = 0;
|
||||
CloseHandle(data->WaveThread);
|
||||
data->WaveThread = 0;
|
||||
|
||||
pData->bWaveShutdown = AL_FALSE;
|
||||
data->killNow = AL_FALSE;
|
||||
|
||||
// Release the wave buffers
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
waveOutUnprepareHeader(pData->hWaveHandle.Out, &pData->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = pData->WaveBuffer[i].lpData;
|
||||
pData->WaveBuffer[i].lpData = NULL;
|
||||
waveOutUnprepareHeader(data->WaveHandle.Out, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = data->WaveBuffer[i].lpData;
|
||||
data->WaveBuffer[i].lpData = NULL;
|
||||
}
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
static ALCenum WinMMOpenCapture(ALCdevice *Device, const ALCchar *deviceName)
|
||||
{
|
||||
ALbyte *BufferData = NULL;
|
||||
DWORD ulCapturedDataSize;
|
||||
WinMMData *pData = NULL;
|
||||
UINT lDeviceID = 0;
|
||||
ALint lBufferSize;
|
||||
DWORD CapturedDataSize;
|
||||
WinMMData *data = NULL;
|
||||
UINT DeviceID = 0;
|
||||
ALint BufferSize;
|
||||
MMRESULT res;
|
||||
ALuint i;
|
||||
|
||||
@@ -511,14 +505,14 @@ static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
if(CaptureDeviceList[i] &&
|
||||
(!deviceName || strcmp(deviceName, CaptureDeviceList[i]) == 0))
|
||||
{
|
||||
lDeviceID = i;
|
||||
DeviceID = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == NumCaptureDevices)
|
||||
return ALC_INVALID_VALUE;
|
||||
|
||||
switch(pDevice->FmtChans)
|
||||
switch(Device->FmtChans)
|
||||
{
|
||||
case DevFmtMono:
|
||||
case DevFmtStereo:
|
||||
@@ -532,7 +526,7 @@ static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
return ALC_INVALID_ENUM;
|
||||
}
|
||||
|
||||
switch(pDevice->FmtType)
|
||||
switch(Device->FmtType)
|
||||
{
|
||||
case DevFmtUByte:
|
||||
case DevFmtShort:
|
||||
@@ -546,167 +540,167 @@ static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
|
||||
return ALC_INVALID_ENUM;
|
||||
}
|
||||
|
||||
pData = calloc(1, sizeof(*pData));
|
||||
if(!pData)
|
||||
data = calloc(1, sizeof(*data));
|
||||
if(!data)
|
||||
return ALC_OUT_OF_MEMORY;
|
||||
pDevice->ExtraData = pData;
|
||||
Device->ExtraData = data;
|
||||
|
||||
memset(&pData->wfexFormat, 0, sizeof(WAVEFORMATEX));
|
||||
pData->wfexFormat.wFormatTag = ((pDevice->FmtType == DevFmtFloat) ?
|
||||
WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
|
||||
pData->wfexFormat.nChannels = ChannelsFromDevFmt(pDevice->FmtChans);
|
||||
pData->wfexFormat.wBitsPerSample = BytesFromDevFmt(pDevice->FmtType) * 8;
|
||||
pData->wfexFormat.nBlockAlign = pData->wfexFormat.wBitsPerSample *
|
||||
pData->wfexFormat.nChannels / 8;
|
||||
pData->wfexFormat.nSamplesPerSec = pDevice->Frequency;
|
||||
pData->wfexFormat.nAvgBytesPerSec = pData->wfexFormat.nSamplesPerSec *
|
||||
pData->wfexFormat.nBlockAlign;
|
||||
pData->wfexFormat.cbSize = 0;
|
||||
memset(&data->Format, 0, sizeof(WAVEFORMATEX));
|
||||
data->Format.wFormatTag = ((Device->FmtType == DevFmtFloat) ?
|
||||
WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
|
||||
data->Format.nChannels = ChannelsFromDevFmt(Device->FmtChans);
|
||||
data->Format.wBitsPerSample = BytesFromDevFmt(Device->FmtType) * 8;
|
||||
data->Format.nBlockAlign = data->Format.wBitsPerSample *
|
||||
data->Format.nChannels / 8;
|
||||
data->Format.nSamplesPerSec = Device->Frequency;
|
||||
data->Format.nAvgBytesPerSec = data->Format.nSamplesPerSec *
|
||||
data->Format.nBlockAlign;
|
||||
data->Format.cbSize = 0;
|
||||
|
||||
if((res=waveInOpen(&pData->hWaveHandle.In, lDeviceID, &pData->wfexFormat, (DWORD_PTR)&WaveInProc, (DWORD_PTR)pDevice, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
if((res=waveInOpen(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR)
|
||||
{
|
||||
ERR("waveInOpen failed: %u\n", res);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
pData->hWaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(pData->hWaveThreadEvent == NULL)
|
||||
data->WaveThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if(data->WaveThreadEvent == NULL)
|
||||
{
|
||||
ERR("CreateEvent failed: %lu\n", GetLastError());
|
||||
goto failure;
|
||||
}
|
||||
|
||||
// Allocate circular memory buffer for the captured audio
|
||||
ulCapturedDataSize = pDevice->UpdateSize*pDevice->NumUpdates;
|
||||
CapturedDataSize = Device->UpdateSize*Device->NumUpdates;
|
||||
|
||||
// Make sure circular buffer is at least 100ms in size
|
||||
if(ulCapturedDataSize < (pData->wfexFormat.nSamplesPerSec / 10))
|
||||
ulCapturedDataSize = pData->wfexFormat.nSamplesPerSec / 10;
|
||||
if(CapturedDataSize < (data->Format.nSamplesPerSec / 10))
|
||||
CapturedDataSize = data->Format.nSamplesPerSec / 10;
|
||||
|
||||
pData->pRing = CreateRingBuffer(pData->wfexFormat.nBlockAlign, ulCapturedDataSize);
|
||||
if(!pData->pRing)
|
||||
data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize);
|
||||
if(!data->Ring)
|
||||
goto failure;
|
||||
|
||||
pData->lWaveBuffersCommitted = 0;
|
||||
data->WaveBuffersCommitted = 0;
|
||||
|
||||
// Create 4 Buffers of 50ms each
|
||||
lBufferSize = pData->wfexFormat.nAvgBytesPerSec / 20;
|
||||
lBufferSize -= (lBufferSize % pData->wfexFormat.nBlockAlign);
|
||||
BufferSize = data->Format.nAvgBytesPerSec / 20;
|
||||
BufferSize -= (BufferSize % data->Format.nBlockAlign);
|
||||
|
||||
BufferData = calloc(4, lBufferSize);
|
||||
BufferData = calloc(4, BufferSize);
|
||||
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);
|
||||
memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR));
|
||||
data->WaveBuffer[i].dwBufferLength = BufferSize;
|
||||
data->WaveBuffer[i].lpData = ((i==0) ? (LPSTR)BufferData :
|
||||
(data->WaveBuffer[i-1].lpData +
|
||||
data->WaveBuffer[i-1].dwBufferLength));
|
||||
data->WaveBuffer[i].dwFlags = 0;
|
||||
data->WaveBuffer[i].dwLoops = 0;
|
||||
waveInPrepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
waveInAddBuffer(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
InterlockedIncrement(&data->WaveBuffersCommitted);
|
||||
}
|
||||
|
||||
pData->hWaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)pDevice, 0, &pData->ulWaveThreadID);
|
||||
if (pData->hWaveThread == NULL)
|
||||
data->WaveThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CaptureThreadProc, (LPVOID)Device, 0, &data->WaveThreadID);
|
||||
if (data->WaveThread == NULL)
|
||||
goto failure;
|
||||
|
||||
pDevice->szDeviceName = strdup(CaptureDeviceList[lDeviceID]);
|
||||
Device->DeviceName = strdup(CaptureDeviceList[DeviceID]);
|
||||
return ALC_NO_ERROR;
|
||||
|
||||
failure:
|
||||
if(pData->hWaveThread)
|
||||
CloseHandle(pData->hWaveThread);
|
||||
if(data->WaveThread)
|
||||
CloseHandle(data->WaveThread);
|
||||
|
||||
if(BufferData)
|
||||
{
|
||||
for(i = 0;i < 4;i++)
|
||||
waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
free(BufferData);
|
||||
}
|
||||
|
||||
if(pData->pRing)
|
||||
DestroyRingBuffer(pData->pRing);
|
||||
if(data->Ring)
|
||||
DestroyRingBuffer(data->Ring);
|
||||
|
||||
if(pData->hWaveThreadEvent)
|
||||
CloseHandle(pData->hWaveThreadEvent);
|
||||
if(data->WaveThreadEvent)
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
|
||||
if(pData->hWaveHandle.In)
|
||||
waveInClose(pData->hWaveHandle.In);
|
||||
if(data->WaveHandle.In)
|
||||
waveInClose(data->WaveHandle.In);
|
||||
|
||||
free(pData);
|
||||
pDevice->ExtraData = NULL;
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
return ALC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
static void WinMMCloseCapture(ALCdevice *pDevice)
|
||||
static void WinMMCloseCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
void *buffer = NULL;
|
||||
int i;
|
||||
|
||||
/* Tell the processing thread to quit and wait for it to do so. */
|
||||
pData->bWaveShutdown = AL_TRUE;
|
||||
PostThreadMessage(pData->ulWaveThreadID, WM_QUIT, 0, 0);
|
||||
data->killNow = AL_TRUE;
|
||||
PostThreadMessage(data->WaveThreadID, WM_QUIT, 0, 0);
|
||||
|
||||
WaitForSingleObjectEx(pData->hWaveThreadEvent, 5000, FALSE);
|
||||
WaitForSingleObjectEx(data->WaveThreadEvent, 5000, FALSE);
|
||||
|
||||
/* Make sure capture is stopped and all pending buffers are flushed. */
|
||||
waveInReset(pData->hWaveHandle.In);
|
||||
waveInReset(data->WaveHandle.In);
|
||||
|
||||
CloseHandle(pData->hWaveThread);
|
||||
pData->hWaveThread = 0;
|
||||
CloseHandle(data->WaveThread);
|
||||
data->WaveThread = 0;
|
||||
|
||||
// Release the wave buffers
|
||||
for(i = 0;i < 4;i++)
|
||||
{
|
||||
waveInUnprepareHeader(pData->hWaveHandle.In, &pData->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = pData->WaveBuffer[i].lpData;
|
||||
pData->WaveBuffer[i].lpData = NULL;
|
||||
waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR));
|
||||
if(i == 0) buffer = data->WaveBuffer[i].lpData;
|
||||
data->WaveBuffer[i].lpData = NULL;
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
DestroyRingBuffer(pData->pRing);
|
||||
pData->pRing = NULL;
|
||||
DestroyRingBuffer(data->Ring);
|
||||
data->Ring = NULL;
|
||||
|
||||
// Close the Wave device
|
||||
CloseHandle(pData->hWaveThreadEvent);
|
||||
pData->hWaveThreadEvent = 0;
|
||||
CloseHandle(data->WaveThreadEvent);
|
||||
data->WaveThreadEvent = 0;
|
||||
|
||||
waveInClose(pData->hWaveHandle.In);
|
||||
pData->hWaveHandle.In = 0;
|
||||
waveInClose(data->WaveHandle.In);
|
||||
data->WaveHandle.In = 0;
|
||||
|
||||
free(pData);
|
||||
pDevice->ExtraData = NULL;
|
||||
free(data);
|
||||
Device->ExtraData = NULL;
|
||||
}
|
||||
|
||||
static void WinMMStartCapture(ALCdevice *pDevice)
|
||||
static void WinMMStartCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
waveInStart(pData->hWaveHandle.In);
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
waveInStart(data->WaveHandle.In);
|
||||
}
|
||||
|
||||
static void WinMMStopCapture(ALCdevice *pDevice)
|
||||
static void WinMMStopCapture(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
waveInStop(pData->hWaveHandle.In);
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
waveInStop(data->WaveHandle.In);
|
||||
}
|
||||
|
||||
static ALCenum WinMMCaptureSamples(ALCdevice *pDevice, ALCvoid *pBuffer, ALCuint lSamples)
|
||||
static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
ReadRingBuffer(pData->pRing, pBuffer, lSamples);
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
ReadRingBuffer(data->Ring, Buffer, Samples);
|
||||
return ALC_NO_ERROR;
|
||||
}
|
||||
|
||||
static ALCuint WinMMAvailableSamples(ALCdevice *pDevice)
|
||||
static ALCuint WinMMAvailableSamples(ALCdevice *Device)
|
||||
{
|
||||
WinMMData *pData = (WinMMData*)pDevice->ExtraData;
|
||||
return RingBufferSize(pData->pRing);
|
||||
WinMMData *data = (WinMMData*)Device->ExtraData;
|
||||
return RingBufferSize(data->Ring);
|
||||
}
|
||||
|
||||
|
||||
@@ -721,7 +715,10 @@ static const BackendFuncs WinMMFuncs = {
|
||||
WinMMStartCapture,
|
||||
WinMMStopCapture,
|
||||
WinMMCaptureSamples,
|
||||
WinMMAvailableSamples
|
||||
WinMMAvailableSamples,
|
||||
ALCdevice_LockDefault,
|
||||
ALCdevice_UnlockDefault,
|
||||
ALCdevice_GetLatencyDefault
|
||||
};
|
||||
|
||||
ALCboolean alcWinMMInit(BackendFuncs *FuncList)
|
||||
@@ -732,18 +729,18 @@ ALCboolean alcWinMMInit(BackendFuncs *FuncList)
|
||||
|
||||
void alcWinMMDeinit()
|
||||
{
|
||||
ALuint lLoop;
|
||||
ALuint i;
|
||||
|
||||
for(lLoop = 0;lLoop < NumPlaybackDevices;lLoop++)
|
||||
free(PlaybackDeviceList[lLoop]);
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
free(PlaybackDeviceList[i]);
|
||||
free(PlaybackDeviceList);
|
||||
PlaybackDeviceList = NULL;
|
||||
|
||||
NumPlaybackDevices = 0;
|
||||
|
||||
|
||||
for(lLoop = 0; lLoop < NumCaptureDevices; lLoop++)
|
||||
free(CaptureDeviceList[lLoop]);
|
||||
for(i = 0;i < NumCaptureDevices;i++)
|
||||
free(CaptureDeviceList[i]);
|
||||
free(CaptureDeviceList);
|
||||
CaptureDeviceList = NULL;
|
||||
|
||||
@@ -761,7 +758,7 @@ void alcWinMMProbe(enum DevProbe type)
|
||||
for(i = 0;i < NumPlaybackDevices;i++)
|
||||
{
|
||||
if(PlaybackDeviceList[i])
|
||||
AppendAllDeviceList(PlaybackDeviceList[i]);
|
||||
AppendAllDevicesList(PlaybackDeviceList[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+215
-7
@@ -21,8 +21,11 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_GUIDDEF_H) || defined(HAVE_INITGUID_H)
|
||||
@@ -46,14 +49,213 @@ DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7,0xbf, 0xa
|
||||
|
||||
#ifdef HAVE_MMDEVAPI
|
||||
#include <devpropdef.h>
|
||||
|
||||
DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#ifdef HAVE_CPUID_H
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#ifdef HAVE_FLOAT_H
|
||||
#include <float.h>
|
||||
#endif
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#include "alMain.h"
|
||||
|
||||
ALuint CPUCapFlags = 0;
|
||||
|
||||
|
||||
void FillCPUCaps(ALuint capfilter)
|
||||
{
|
||||
ALuint caps = 0;
|
||||
|
||||
/* FIXME: We really should get this for all available CPUs in case different
|
||||
* CPUs have different caps (is that possible on one machine?). */
|
||||
#if defined(HAVE_CPUID_H) && (defined(__i386__) || defined(__x86_64__) || \
|
||||
defined(_M_IX86) || defined(_M_X64))
|
||||
union {
|
||||
unsigned int regs[4];
|
||||
char str[sizeof(unsigned int[4])];
|
||||
} cpuinf[3];
|
||||
|
||||
if(!__get_cpuid(0, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
ERR("Failed to get CPUID\n");
|
||||
else
|
||||
{
|
||||
unsigned int maxfunc = cpuinf[0].regs[0];
|
||||
unsigned int maxextfunc = 0;
|
||||
|
||||
if(__get_cpuid(0x80000000, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
maxextfunc = cpuinf[0].regs[0];
|
||||
TRACE("Detected max CPUID function: 0x%x (ext. 0x%x)\n", maxfunc, maxextfunc);
|
||||
|
||||
TRACE("Vendor ID: \"%.4s%.4s%.4s\"\n", cpuinf[0].str+4, cpuinf[0].str+12, cpuinf[0].str+8);
|
||||
if(maxextfunc >= 0x80000004 &&
|
||||
__get_cpuid(0x80000002, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]) &&
|
||||
__get_cpuid(0x80000003, &cpuinf[1].regs[0], &cpuinf[1].regs[1], &cpuinf[1].regs[2], &cpuinf[1].regs[3]) &&
|
||||
__get_cpuid(0x80000004, &cpuinf[2].regs[0], &cpuinf[2].regs[1], &cpuinf[2].regs[2], &cpuinf[2].regs[3]))
|
||||
TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str);
|
||||
|
||||
if(maxfunc >= 1 &&
|
||||
__get_cpuid(1, &cpuinf[0].regs[0], &cpuinf[0].regs[1], &cpuinf[0].regs[2], &cpuinf[0].regs[3]))
|
||||
{
|
||||
#ifdef bit_SSE
|
||||
if((cpuinf[0].regs[3]&bit_SSE))
|
||||
caps |= CPU_CAP_SSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_WINDOWS_H)
|
||||
HMODULE k32 = GetModuleHandleA("kernel32.dll");
|
||||
BOOL (WINAPI*IsProcessorFeaturePresent)(DWORD ProcessorFeature);
|
||||
IsProcessorFeaturePresent = (BOOL(WINAPI*)(DWORD))GetProcAddress(k32, "IsProcessorFeaturePresent");
|
||||
if(!IsProcessorFeaturePresent)
|
||||
ERR("IsProcessorFeaturePresent not available; CPU caps not detected\n");
|
||||
else
|
||||
{
|
||||
if(IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE))
|
||||
caps |= CPU_CAP_SSE;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NEON
|
||||
/* Assume Neon support if compiled with it */
|
||||
caps |= CPU_CAP_NEON;
|
||||
#endif
|
||||
|
||||
TRACE("Got caps:%s%s%s\n", ((caps&CPU_CAP_SSE)?((capfilter&CPU_CAP_SSE)?" SSE":" (SSE)"):""),
|
||||
((caps&CPU_CAP_NEON)?((capfilter&CPU_CAP_NEON)?" Neon":" (Neon)"):""),
|
||||
((!caps)?" -none-":""));
|
||||
CPUCapFlags = caps & capfilter;
|
||||
}
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size)
|
||||
{
|
||||
#if defined(HAVE_ALIGNED_ALLOC)
|
||||
size = (size+(alignment-1))&~(alignment-1);
|
||||
return aligned_alloc(alignment, size);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
void *ret;
|
||||
if(posix_memalign(&ret, alignment, size) == 0)
|
||||
return ret;
|
||||
return NULL;
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
return _aligned_malloc(size, alignment);
|
||||
#else
|
||||
char *ret = malloc(size+alignment);
|
||||
if(ret != NULL)
|
||||
{
|
||||
*(ret++) = 0x00;
|
||||
while(((ALintptrEXT)ret&(alignment-1)) != 0)
|
||||
*(ret++) = 0x55;
|
||||
}
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *al_calloc(size_t alignment, size_t size)
|
||||
{
|
||||
void *ret = al_malloc(alignment, size);
|
||||
if(ret) memset(ret, 0, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void al_free(void *ptr)
|
||||
{
|
||||
#if defined(HAVE_ALIGNED_ALLOC) || defined(HAVE_POSIX_MEMALIGN)
|
||||
free(ptr);
|
||||
#elif defined(HAVE__ALIGNED_MALLOC)
|
||||
_aligned_free(ptr);
|
||||
#else
|
||||
if(ptr != NULL)
|
||||
{
|
||||
char *finder = ptr;
|
||||
do {
|
||||
--finder;
|
||||
} while(*finder == 0x55);
|
||||
free(finder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if (defined(HAVE___CONTROL87_2) || defined(HAVE__CONTROLFP)) && (defined(__x86_64__) || defined(_M_X64))
|
||||
/* Win64 doesn't allow us to set the precision control. */
|
||||
#undef _MCW_PC
|
||||
#define _MCW_PC 0
|
||||
#endif
|
||||
|
||||
void SetMixerFPUMode(FPUCtl *ctl)
|
||||
{
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
unsigned short fpuState;
|
||||
__asm__ __volatile__("fnstcw %0" : "=m" (*&fpuState));
|
||||
ctl->state = fpuState;
|
||||
fpuState &= ~0x300; /* clear precision to single */
|
||||
fpuState |= 0xC00; /* set round-to-zero */
|
||||
__asm__ __volatile__("fldcw %0" : : "m" (*&fpuState));
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
{
|
||||
int sseState;
|
||||
__asm__ __volatile__("stmxcsr %0" : "=m" (*&sseState));
|
||||
ctl->sse_state = sseState;
|
||||
sseState |= 0x0C00; /* set round-to-zero */
|
||||
sseState |= 0x8000; /* set flush-to-zero */
|
||||
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&sseState));
|
||||
}
|
||||
#endif
|
||||
#elif defined(HAVE___CONTROL87_2)
|
||||
int mode;
|
||||
__control87_2(0, 0, &ctl->state, NULL);
|
||||
__control87_2(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC, &mode, NULL);
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
{
|
||||
__control87_2(0, 0, NULL, &ctl->sse_state);
|
||||
__control87_2(_RC_CHOP|_DN_FLUSH, _MCW_RC|_MCW_DN, NULL, &mode);
|
||||
}
|
||||
#endif
|
||||
#elif defined(HAVE__CONTROLFP)
|
||||
ctl->state = _controlfp(0, 0);
|
||||
(void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
ctl->state = fegetround();
|
||||
#ifdef FE_TOWARDZERO
|
||||
fesetround(FE_TOWARDZERO);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void RestoreFPUMode(const FPUCtl *ctl)
|
||||
{
|
||||
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
unsigned short fpuState = ctl->state;
|
||||
__asm__ __volatile__("fldcw %0" : : "m" (*&fpuState));
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&ctl->sse_state));
|
||||
#endif
|
||||
#elif defined(HAVE___CONTROL87_2)
|
||||
int mode;
|
||||
__control87_2(ctl->state, _MCW_RC|_MCW_PC, &mode, NULL);
|
||||
#ifdef HAVE_SSE
|
||||
if((CPUCapFlags&CPU_CAP_SSE))
|
||||
__control87_2(ctl->sse_state, _MCW_RC|_MCW_DN, NULL, &mode);
|
||||
#endif
|
||||
#elif defined(HAVE__CONTROLFP)
|
||||
_controlfp(ctl->state, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
fesetround(ctl->state);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
void pthread_once(pthread_once_t *once, void (*callback)(void))
|
||||
{
|
||||
@@ -123,6 +325,12 @@ WCHAR *strdupW(const WCHAR *str)
|
||||
|
||||
#else
|
||||
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
#include <sched.h>
|
||||
|
||||
void InitializeCriticalSection(CRITICAL_SECTION *cs)
|
||||
{
|
||||
pthread_mutexattr_t attrib;
|
||||
@@ -239,13 +447,13 @@ void *GetSymbol(void *handle, const char *name)
|
||||
#endif
|
||||
|
||||
|
||||
void al_print(const char *func, const char *fmt, ...)
|
||||
void al_print(const char *type, const char *func, const char *fmt, ...)
|
||||
{
|
||||
char str[256];
|
||||
int i;
|
||||
|
||||
i = snprintf(str, sizeof(str), "AL lib: %s: ", func);
|
||||
if(i < (int)sizeof(str) && i > 0)
|
||||
i = snprintf(str, sizeof(str), "AL lib: %s %s: ", type, func);
|
||||
if(i > 0 && (unsigned int)i < sizeof(str))
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
+621
-274
File diff suppressed because it is too large
Load Diff
+846
-837
File diff suppressed because it is too large
Load Diff
+238
-639
@@ -37,437 +37,6 @@
|
||||
#include "bs2b.h"
|
||||
|
||||
|
||||
static __inline ALfloat point32(const ALfloat *vals, ALint step, ALint frac)
|
||||
{ return vals[0]; (void)step; (void)frac; }
|
||||
static __inline ALfloat lerp32(const ALfloat *vals, ALint step, ALint frac)
|
||||
{ return lerp(vals[0], vals[step], frac * (1.0f/FRACTIONONE)); }
|
||||
static __inline ALfloat cubic32(const ALfloat *vals, ALint step, ALint frac)
|
||||
{ return cubic(vals[-step], vals[0], vals[step], vals[step+step],
|
||||
frac * (1.0f/FRACTIONONE)); }
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define LIKELY(x) (x)
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_NEON__) && defined(HAVE_ARM_NEON_H)
|
||||
#include <arm_neon.h>
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
float32x4_t leftright4;
|
||||
{
|
||||
float32x2_t leftright2 = vdup_n_f32(0.0);
|
||||
leftright2 = vset_lane_f32(left, leftright2, 0);
|
||||
leftright2 = vset_lane_f32(right, leftright2, 1);
|
||||
leftright4 = vcombine_f32(leftright2, leftright2);
|
||||
}
|
||||
for(c = 0;c < HRIR_LENGTH;c += 2)
|
||||
{
|
||||
const ALuint o0 = (Offset+c)&HRIR_MASK;
|
||||
const ALuint o1 = (o0+1)&HRIR_MASK;
|
||||
float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]),
|
||||
vld1_f32((float32_t*)&Values[o1][0]));
|
||||
float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]);
|
||||
|
||||
vals = vmlaq_f32(vals, coefs, leftright4);
|
||||
|
||||
vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
|
||||
vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < HRIR_LENGTH;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define DECL_TEMPLATE(T, sampler) \
|
||||
static void Mix_Hrtf_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
|
||||
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
|
||||
{ \
|
||||
const ALuint NumChannels = Source->NumChannels; \
|
||||
const T *RESTRICT data = srcdata; \
|
||||
const ALint *RESTRICT DelayStep = Source->Params.HrtfDelayStep; \
|
||||
ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
|
||||
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
|
||||
ALfloat (*RESTRICT CoeffStep)[2] = Source->Params.HrtfCoeffStep; \
|
||||
ALuint pos, frac; \
|
||||
FILTER *DryFilter; \
|
||||
ALuint BufferIdx; \
|
||||
ALuint increment; \
|
||||
ALuint i, out, c; \
|
||||
ALfloat value; \
|
||||
\
|
||||
increment = Source->Params.Step; \
|
||||
\
|
||||
DryBuffer = Device->DryBuffer; \
|
||||
ClickRemoval = Device->ClickRemoval; \
|
||||
PendingClicks = Device->PendingClicks; \
|
||||
DryFilter = &Source->Params.iirFilter; \
|
||||
\
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
for(i = 0;i < NumChannels;i++) \
|
||||
{ \
|
||||
ALfloat (*RESTRICT TargetCoeffs)[2] = Source->Params.HrtfCoeffs[i]; \
|
||||
ALuint *RESTRICT TargetDelay = Source->Params.HrtfDelay[i]; \
|
||||
ALfloat *RESTRICT History = Source->HrtfHistory[i]; \
|
||||
ALfloat (*RESTRICT Values)[2] = Source->HrtfValues[i]; \
|
||||
ALint Counter = maxu(Source->HrtfCounter, OutPos) - OutPos; \
|
||||
ALuint Offset = Source->HrtfOffset + OutPos; \
|
||||
ALfloat Coeffs[HRIR_LENGTH][2]; \
|
||||
ALuint Delay[2]; \
|
||||
ALfloat left, right; \
|
||||
\
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
for(c = 0;c < HRIR_LENGTH;c++) \
|
||||
{ \
|
||||
Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter); \
|
||||
Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter); \
|
||||
} \
|
||||
\
|
||||
Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter) + 32768; \
|
||||
Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter) + 32768; \
|
||||
\
|
||||
if(LIKELY(OutPos == 0)) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
value = lpFilter2PC(DryFilter, i, value); \
|
||||
\
|
||||
History[Offset&SRC_HISTORY_MASK] = value; \
|
||||
left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
|
||||
right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
|
||||
\
|
||||
ClickRemoval[FRONT_LEFT] -= Values[(Offset+1)&HRIR_MASK][0] + \
|
||||
Coeffs[0][0] * left; \
|
||||
ClickRemoval[FRONT_RIGHT] -= Values[(Offset+1)&HRIR_MASK][1] + \
|
||||
Coeffs[0][1] * right; \
|
||||
} \
|
||||
for(BufferIdx = 0;BufferIdx < BufferSize && Counter > 0;BufferIdx++) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
value = lpFilter2P(DryFilter, i, value); \
|
||||
\
|
||||
History[Offset&SRC_HISTORY_MASK] = value; \
|
||||
left = History[(Offset-(Delay[0]>>16))&SRC_HISTORY_MASK]; \
|
||||
right = History[(Offset-(Delay[1]>>16))&SRC_HISTORY_MASK]; \
|
||||
\
|
||||
Delay[0] += DelayStep[0]; \
|
||||
Delay[1] += DelayStep[1]; \
|
||||
\
|
||||
Values[Offset&HRIR_MASK][0] = 0.0f; \
|
||||
Values[Offset&HRIR_MASK][1] = 0.0f; \
|
||||
Offset++; \
|
||||
\
|
||||
for(c = 0;c < HRIR_LENGTH;c++) \
|
||||
{ \
|
||||
const ALuint off = (Offset+c)&HRIR_MASK; \
|
||||
Values[off][0] += Coeffs[c][0] * left; \
|
||||
Values[off][1] += Coeffs[c][1] * right; \
|
||||
Coeffs[c][0] += CoeffStep[c][0]; \
|
||||
Coeffs[c][1] += CoeffStep[c][1]; \
|
||||
} \
|
||||
\
|
||||
DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
|
||||
DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
OutPos++; \
|
||||
Counter--; \
|
||||
} \
|
||||
\
|
||||
Delay[0] >>= 16; \
|
||||
Delay[1] >>= 16; \
|
||||
for(;BufferIdx < BufferSize;BufferIdx++) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
value = lpFilter2P(DryFilter, i, value); \
|
||||
\
|
||||
History[Offset&SRC_HISTORY_MASK] = value; \
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
|
||||
\
|
||||
Values[Offset&HRIR_MASK][0] = 0.0f; \
|
||||
Values[Offset&HRIR_MASK][1] = 0.0f; \
|
||||
Offset++; \
|
||||
\
|
||||
ApplyCoeffs(Offset, Values, Coeffs, left, right); \
|
||||
DryBuffer[OutPos][FRONT_LEFT] += Values[Offset&HRIR_MASK][0]; \
|
||||
DryBuffer[OutPos][FRONT_RIGHT] += Values[Offset&HRIR_MASK][1]; \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
OutPos++; \
|
||||
} \
|
||||
if(LIKELY(OutPos == SamplesToDo)) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
value = lpFilter2PC(DryFilter, i, value); \
|
||||
\
|
||||
History[Offset&SRC_HISTORY_MASK] = value; \
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK]; \
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK]; \
|
||||
\
|
||||
PendingClicks[FRONT_LEFT] += Values[(Offset+1)&HRIR_MASK][0] + \
|
||||
Coeffs[0][0] * left; \
|
||||
PendingClicks[FRONT_RIGHT] += Values[(Offset+1)&HRIR_MASK][1] + \
|
||||
Coeffs[0][1] * right; \
|
||||
} \
|
||||
OutPos -= BufferSize; \
|
||||
} \
|
||||
\
|
||||
for(out = 0;out < Device->NumAuxSends;out++) \
|
||||
{ \
|
||||
ALeffectslot *Slot = Source->Params.Send[out].Slot; \
|
||||
ALfloat WetSend; \
|
||||
ALfloat *RESTRICT WetBuffer; \
|
||||
ALfloat *RESTRICT WetClickRemoval; \
|
||||
ALfloat *RESTRICT WetPendingClicks; \
|
||||
FILTER *WetFilter; \
|
||||
\
|
||||
if(Slot == NULL) \
|
||||
continue; \
|
||||
\
|
||||
WetBuffer = Slot->WetBuffer; \
|
||||
WetClickRemoval = Slot->ClickRemoval; \
|
||||
WetPendingClicks = Slot->PendingClicks; \
|
||||
WetFilter = &Source->Params.Send[out].iirFilter; \
|
||||
WetSend = Source->Params.Send[out].WetGain; \
|
||||
\
|
||||
for(i = 0;i < NumChannels;i++) \
|
||||
{ \
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
if(LIKELY(OutPos == 0)) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
value = lpFilter1PC(WetFilter, i, value); \
|
||||
\
|
||||
WetClickRemoval[0] -= value * WetSend; \
|
||||
} \
|
||||
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
value = lpFilter1P(WetFilter, i, value); \
|
||||
\
|
||||
WetBuffer[OutPos] += value * WetSend; \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
OutPos++; \
|
||||
} \
|
||||
if(LIKELY(OutPos == SamplesToDo)) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
value = lpFilter1PC(WetFilter, i, value); \
|
||||
\
|
||||
WetPendingClicks[0] += value * WetSend; \
|
||||
} \
|
||||
OutPos -= BufferSize; \
|
||||
} \
|
||||
} \
|
||||
*DataPosInt += pos; \
|
||||
*DataPosFrac = frac; \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(ALfloat, point32)
|
||||
DECL_TEMPLATE(ALfloat, lerp32)
|
||||
DECL_TEMPLATE(ALfloat, cubic32)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
#define DECL_TEMPLATE(T, sampler) \
|
||||
static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
|
||||
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
|
||||
{ \
|
||||
const ALuint NumChannels = Source->NumChannels; \
|
||||
const T *RESTRICT data = srcdata; \
|
||||
ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
|
||||
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
|
||||
ALfloat DrySend[MAXCHANNELS]; \
|
||||
FILTER *DryFilter; \
|
||||
ALuint pos, frac; \
|
||||
ALuint BufferIdx; \
|
||||
ALuint increment; \
|
||||
ALuint i, out, c; \
|
||||
ALfloat value; \
|
||||
\
|
||||
increment = Source->Params.Step; \
|
||||
\
|
||||
DryBuffer = Device->DryBuffer; \
|
||||
ClickRemoval = Device->ClickRemoval; \
|
||||
PendingClicks = Device->PendingClicks; \
|
||||
DryFilter = &Source->Params.iirFilter; \
|
||||
\
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
for(i = 0;i < NumChannels;i++) \
|
||||
{ \
|
||||
for(c = 0;c < MAXCHANNELS;c++) \
|
||||
DrySend[c] = Source->Params.DryGains[i][c]; \
|
||||
\
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
if(OutPos == 0) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
\
|
||||
value = lpFilter2PC(DryFilter, i, value); \
|
||||
for(c = 0;c < MAXCHANNELS;c++) \
|
||||
ClickRemoval[c] -= value*DrySend[c]; \
|
||||
} \
|
||||
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
\
|
||||
value = lpFilter2P(DryFilter, i, value); \
|
||||
for(c = 0;c < MAXCHANNELS;c++) \
|
||||
DryBuffer[OutPos][c] += value*DrySend[c]; \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
OutPos++; \
|
||||
} \
|
||||
if(OutPos == SamplesToDo) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels, frac); \
|
||||
\
|
||||
value = lpFilter2PC(DryFilter, i, value); \
|
||||
for(c = 0;c < MAXCHANNELS;c++) \
|
||||
PendingClicks[c] += value*DrySend[c]; \
|
||||
} \
|
||||
OutPos -= BufferSize; \
|
||||
} \
|
||||
\
|
||||
for(out = 0;out < Device->NumAuxSends;out++) \
|
||||
{ \
|
||||
ALeffectslot *Slot = Source->Params.Send[out].Slot; \
|
||||
ALfloat WetSend; \
|
||||
ALfloat *WetBuffer; \
|
||||
ALfloat *WetClickRemoval; \
|
||||
ALfloat *WetPendingClicks; \
|
||||
FILTER *WetFilter; \
|
||||
\
|
||||
if(Slot == NULL) \
|
||||
continue; \
|
||||
\
|
||||
WetBuffer = Slot->WetBuffer; \
|
||||
WetClickRemoval = Slot->ClickRemoval; \
|
||||
WetPendingClicks = Slot->PendingClicks; \
|
||||
WetFilter = &Source->Params.Send[out].iirFilter; \
|
||||
WetSend = Source->Params.Send[out].WetGain; \
|
||||
\
|
||||
for(i = 0;i < NumChannels;i++) \
|
||||
{ \
|
||||
pos = 0; \
|
||||
frac = *DataPosFrac; \
|
||||
\
|
||||
if(OutPos == 0) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
\
|
||||
value = lpFilter1PC(WetFilter, i, value); \
|
||||
WetClickRemoval[0] -= value * WetSend; \
|
||||
} \
|
||||
for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
\
|
||||
value = lpFilter1P(WetFilter, i, value); \
|
||||
WetBuffer[OutPos] += value * WetSend; \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
OutPos++; \
|
||||
} \
|
||||
if(OutPos == SamplesToDo) \
|
||||
{ \
|
||||
value = sampler(data + pos*NumChannels + i, NumChannels,frac);\
|
||||
\
|
||||
value = lpFilter1PC(WetFilter, i, value); \
|
||||
WetPendingClicks[0] += value * WetSend; \
|
||||
} \
|
||||
OutPos -= BufferSize; \
|
||||
} \
|
||||
} \
|
||||
*DataPosInt += pos; \
|
||||
*DataPosFrac = frac; \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(ALfloat, point32)
|
||||
DECL_TEMPLATE(ALfloat, lerp32)
|
||||
DECL_TEMPLATE(ALfloat, cubic32)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
MixerFunc SelectMixer(enum Resampler Resampler)
|
||||
{
|
||||
switch(Resampler)
|
||||
{
|
||||
case PointResampler:
|
||||
return Mix_ALfloat_point32;
|
||||
case LinearResampler:
|
||||
return Mix_ALfloat_lerp32;
|
||||
case CubicResampler:
|
||||
return Mix_ALfloat_cubic32;
|
||||
case ResamplerMax:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MixerFunc SelectHrtfMixer(enum Resampler Resampler)
|
||||
{
|
||||
switch(Resampler)
|
||||
{
|
||||
case PointResampler:
|
||||
return Mix_Hrtf_ALfloat_point32;
|
||||
case LinearResampler:
|
||||
return Mix_Hrtf_ALfloat_lerp32;
|
||||
case CubicResampler:
|
||||
return Mix_Hrtf_ALfloat_cubic32;
|
||||
case ResamplerMax:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static __inline ALfloat Sample_ALbyte(ALbyte val)
|
||||
{ return val * (1.0f/127.0f); }
|
||||
|
||||
@@ -478,11 +47,11 @@ static __inline ALfloat Sample_ALfloat(ALfloat val)
|
||||
{ return val; }
|
||||
|
||||
#define DECL_TEMPLATE(T) \
|
||||
static void Load_##T(ALfloat *dst, const T *src, ALuint samples) \
|
||||
static void Load_##T(ALfloat *dst, const T *src, ALuint srcstep, ALuint samples)\
|
||||
{ \
|
||||
ALuint i; \
|
||||
for(i = 0;i < samples;i++) \
|
||||
dst[i] = Sample_##T(src[i]); \
|
||||
dst[i] = Sample_##T(src[i*srcstep]); \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(ALbyte)
|
||||
@@ -491,23 +60,23 @@ DECL_TEMPLATE(ALfloat)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
static void LoadStack(ALfloat *dst, const ALvoid *src, enum FmtType srctype, ALuint samples)
|
||||
static void LoadData(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples)
|
||||
{
|
||||
switch(srctype)
|
||||
{
|
||||
case FmtByte:
|
||||
Load_ALbyte(dst, src, samples);
|
||||
Load_ALbyte(dst, src, srcstep, samples);
|
||||
break;
|
||||
case FmtShort:
|
||||
Load_ALshort(dst, src, samples);
|
||||
Load_ALshort(dst, src, srcstep, samples);
|
||||
break;
|
||||
case FmtFloat:
|
||||
Load_ALfloat(dst, src, samples);
|
||||
Load_ALfloat(dst, src, srcstep, samples);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void SilenceStack(ALfloat *dst, ALuint samples)
|
||||
static void SilenceData(ALfloat *dst, ALuint samples)
|
||||
{
|
||||
ALuint i;
|
||||
for(i = 0;i < samples;i++)
|
||||
@@ -515,6 +84,16 @@ static void SilenceStack(ALfloat *dst, ALuint samples)
|
||||
}
|
||||
|
||||
|
||||
static void Filter2P(FILTER *filter, ALuint chan, ALfloat *RESTRICT dst,
|
||||
const ALfloat *RESTRICT src, ALuint numsamples)
|
||||
{
|
||||
ALuint i;
|
||||
for(i = 0;i < numsamples;i++)
|
||||
dst[i] = lpFilter2P(filter, chan, src[i]);
|
||||
dst[i] = lpFilter2PC(filter, chan, src[i]);
|
||||
}
|
||||
|
||||
|
||||
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
ALbufferlistitem *BufferListItem;
|
||||
@@ -526,34 +105,31 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
ALenum State;
|
||||
ALuint OutPos;
|
||||
ALuint NumChannels;
|
||||
ALuint FrameSize;
|
||||
ALuint SampleSize;
|
||||
ALint64 DataSize64;
|
||||
ALuint i;
|
||||
ALuint chan, j;
|
||||
|
||||
/* Get source info */
|
||||
State = Source->state;
|
||||
BuffersPlayed = Source->BuffersPlayed;
|
||||
DataPosInt = Source->position;
|
||||
DataPosFrac = Source->position_fraction;
|
||||
Looping = Source->bLooping;
|
||||
Looping = Source->Looping;
|
||||
increment = Source->Params.Step;
|
||||
Resampler = Source->Resampler;
|
||||
Resampler = (increment==FRACTIONONE) ? PointResampler : Source->Resampler;
|
||||
NumChannels = Source->NumChannels;
|
||||
FrameSize = NumChannels * Source->SampleSize;
|
||||
SampleSize = Source->SampleSize;
|
||||
|
||||
/* Get current buffer queue item */
|
||||
BufferListItem = Source->queue;
|
||||
for(i = 0;i < BuffersPlayed;i++)
|
||||
for(j = 0;j < BuffersPlayed;j++)
|
||||
BufferListItem = BufferListItem->next;
|
||||
|
||||
OutPos = 0;
|
||||
do {
|
||||
const ALuint BufferPrePadding = ResamplerPrePadding[Resampler];
|
||||
const ALuint BufferPadding = ResamplerPadding[Resampler];
|
||||
ALfloat StackData[STACK_DATA_SIZE/sizeof(ALfloat)];
|
||||
ALfloat *SrcData = StackData;
|
||||
ALuint SrcDataSize = 0;
|
||||
ALuint BufferSize;
|
||||
ALuint SrcBufferSize, DstBufferSize;
|
||||
|
||||
/* Figure out how many buffer bytes will be needed */
|
||||
DataSize64 = SamplesToDo-OutPos+1;
|
||||
@@ -561,197 +137,223 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
DataSize64 += DataPosFrac+FRACTIONMASK;
|
||||
DataSize64 >>= FRACTIONBITS;
|
||||
DataSize64 += BufferPadding+BufferPrePadding;
|
||||
DataSize64 *= NumChannels;
|
||||
|
||||
BufferSize = (ALuint)mini64(DataSize64, STACK_DATA_SIZE/sizeof(ALfloat));
|
||||
BufferSize /= NumChannels;
|
||||
SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE);
|
||||
|
||||
if(Source->lSourceType == AL_STATIC)
|
||||
{
|
||||
const ALbuffer *ALBuffer = Source->queue->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;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
|
||||
SilenceStack(&SrcData[SrcDataSize*NumChannels],
|
||||
DataSize*NumChannels);
|
||||
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->SampleLen - pos;
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
|
||||
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
|
||||
ALBuffer->FmtType, DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
|
||||
SilenceStack(&SrcData[SrcDataSize*NumChannels],
|
||||
BufferSize*NumChannels);
|
||||
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;
|
||||
}
|
||||
else if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
|
||||
SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Copy what's left of this loop iteration, then copy repeats
|
||||
* of the loop section */
|
||||
DataSize = LoopEnd - pos;
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
|
||||
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[pos*FrameSize],
|
||||
ALBuffer->FmtType, DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
|
||||
DataSize = LoopEnd-LoopStart;
|
||||
while(BufferSize > 0)
|
||||
{
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
|
||||
LoadStack(&SrcData[SrcDataSize*NumChannels], &Data[LoopStart*FrameSize],
|
||||
ALBuffer->FmtType, DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Crawl the buffer queue to fill in the temp buffer */
|
||||
ALbufferlistitem *tmpiter = BufferListItem;
|
||||
ALuint pos;
|
||||
|
||||
if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
pos = BufferPrePadding - DataPosInt;
|
||||
while(pos > 0)
|
||||
{
|
||||
if(!tmpiter->prev && !Looping)
|
||||
{
|
||||
ALuint DataSize = minu(BufferSize, pos);
|
||||
|
||||
SilenceStack(&SrcData[SrcDataSize*NumChannels], DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(tmpiter->prev)
|
||||
tmpiter = tmpiter->prev;
|
||||
else
|
||||
{
|
||||
while(tmpiter->next)
|
||||
tmpiter = tmpiter->next;
|
||||
}
|
||||
|
||||
if(tmpiter->buffer)
|
||||
{
|
||||
if((ALuint)tmpiter->buffer->SampleLen > pos)
|
||||
{
|
||||
pos = tmpiter->buffer->SampleLen - pos;
|
||||
break;
|
||||
}
|
||||
pos -= tmpiter->buffer->SampleLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(tmpiter && BufferSize > 0)
|
||||
{
|
||||
const ALbuffer *ALBuffer;
|
||||
if((ALBuffer=tmpiter->buffer) != NULL)
|
||||
{
|
||||
const ALubyte *Data = ALBuffer->data;
|
||||
ALuint DataSize = ALBuffer->SampleLen;
|
||||
|
||||
/* Skip the data already played */
|
||||
if(DataSize <= pos)
|
||||
pos -= DataSize;
|
||||
else
|
||||
{
|
||||
Data += pos*FrameSize;
|
||||
DataSize -= pos;
|
||||
pos -= pos;
|
||||
|
||||
DataSize = minu(BufferSize, DataSize);
|
||||
LoadStack(&SrcData[SrcDataSize*NumChannels], Data,
|
||||
ALBuffer->FmtType, DataSize*NumChannels);
|
||||
SrcDataSize += DataSize;
|
||||
BufferSize -= DataSize;
|
||||
}
|
||||
}
|
||||
tmpiter = tmpiter->next;
|
||||
if(!tmpiter && Looping)
|
||||
tmpiter = Source->queue;
|
||||
else if(!tmpiter)
|
||||
{
|
||||
SilenceStack(&SrcData[SrcDataSize*NumChannels], BufferSize*NumChannels);
|
||||
SrcDataSize += BufferSize;
|
||||
BufferSize -= BufferSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Figure out how many samples we can mix. */
|
||||
DataSize64 = SrcDataSize;
|
||||
/* Figure out how many samples we can actually mix from this. */
|
||||
DataSize64 = SrcBufferSize;
|
||||
DataSize64 -= BufferPadding+BufferPrePadding;
|
||||
DataSize64 <<= FRACTIONBITS;
|
||||
DataSize64 -= increment;
|
||||
DataSize64 -= DataPosFrac;
|
||||
|
||||
BufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
|
||||
BufferSize = minu(BufferSize, (SamplesToDo-OutPos));
|
||||
DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment);
|
||||
DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos));
|
||||
|
||||
SrcData += BufferPrePadding*NumChannels;
|
||||
Source->Params.DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
|
||||
OutPos, SamplesToDo, BufferSize);
|
||||
OutPos += BufferSize;
|
||||
/* Some mixers like having a multiple of 4, so try to give that unless
|
||||
* this is the last update. */
|
||||
if(OutPos+DstBufferSize < SamplesToDo)
|
||||
DstBufferSize &= ~3;
|
||||
|
||||
for(chan = 0;chan < NumChannels;chan++)
|
||||
{
|
||||
ALfloat *SrcData = Device->SampleData1;
|
||||
ALfloat *ResampledData = Device->SampleData2;
|
||||
ALuint SrcDataSize = 0;
|
||||
|
||||
if(Source->SourceType == AL_STATIC)
|
||||
{
|
||||
const ALbuffer *ALBuffer = Source->queue->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;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Copy what's left to play in the source buffer, and clear the
|
||||
* rest of the temp buffer */
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, ALBuffer->SampleLen - pos);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
/* Copy what's left of this loop iteration, then copy repeats
|
||||
* of the loop section */
|
||||
DataSize = LoopEnd - pos;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
DataSize = LoopEnd-LoopStart;
|
||||
while(SrcBufferSize > SrcDataSize)
|
||||
{
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Crawl the buffer queue to fill in the temp buffer */
|
||||
ALbufferlistitem *tmpiter = BufferListItem;
|
||||
ALuint pos;
|
||||
|
||||
if(DataPosInt >= BufferPrePadding)
|
||||
pos = DataPosInt - BufferPrePadding;
|
||||
else
|
||||
{
|
||||
pos = BufferPrePadding - DataPosInt;
|
||||
while(pos > 0)
|
||||
{
|
||||
if(!tmpiter->prev && !Looping)
|
||||
{
|
||||
ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(tmpiter->prev)
|
||||
tmpiter = tmpiter->prev;
|
||||
else
|
||||
{
|
||||
while(tmpiter->next)
|
||||
tmpiter = tmpiter->next;
|
||||
}
|
||||
|
||||
if(tmpiter->buffer)
|
||||
{
|
||||
if((ALuint)tmpiter->buffer->SampleLen > pos)
|
||||
{
|
||||
pos = tmpiter->buffer->SampleLen - pos;
|
||||
break;
|
||||
}
|
||||
pos -= tmpiter->buffer->SampleLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(tmpiter && SrcBufferSize > SrcDataSize)
|
||||
{
|
||||
const ALbuffer *ALBuffer;
|
||||
if((ALBuffer=tmpiter->buffer) != NULL)
|
||||
{
|
||||
const ALubyte *Data = ALBuffer->data;
|
||||
ALuint DataSize = ALBuffer->SampleLen;
|
||||
|
||||
/* Skip the data already played */
|
||||
if(DataSize <= pos)
|
||||
pos -= DataSize;
|
||||
else
|
||||
{
|
||||
Data += (pos*NumChannels + chan)*SampleSize;
|
||||
DataSize -= pos;
|
||||
pos -= pos;
|
||||
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
LoadData(&SrcData[SrcDataSize], Data, NumChannels,
|
||||
ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
tmpiter = tmpiter->next;
|
||||
if(!tmpiter && Looping)
|
||||
tmpiter = Source->queue;
|
||||
else if(!tmpiter)
|
||||
{
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now resample, then filter and mix to the appropriate outputs. */
|
||||
Source->Params.Resample(&SrcData[BufferPrePadding], DataPosFrac,
|
||||
increment, ResampledData, DstBufferSize);
|
||||
|
||||
{
|
||||
DirectParams *directparms = &Source->Params.Direct;
|
||||
|
||||
Filter2P(&directparms->iirFilter, chan, SrcData, ResampledData,
|
||||
DstBufferSize);
|
||||
Source->Params.DryMix(directparms, SrcData, chan, OutPos,
|
||||
SamplesToDo, DstBufferSize);
|
||||
}
|
||||
|
||||
for(j = 0;j < Device->NumAuxSends;j++)
|
||||
{
|
||||
SendParams *sendparms = &Source->Params.Send[j];
|
||||
if(!sendparms->Slot)
|
||||
continue;
|
||||
|
||||
Filter2P(&sendparms->iirFilter, chan, SrcData, ResampledData,
|
||||
DstBufferSize);
|
||||
Source->Params.WetMix(sendparms, SrcData, OutPos,
|
||||
SamplesToDo, DstBufferSize);
|
||||
}
|
||||
}
|
||||
/* Update positions */
|
||||
for(j = 0;j < DstBufferSize;j++)
|
||||
{
|
||||
DataPosFrac += increment;
|
||||
DataPosInt += DataPosFrac>>FRACTIONBITS;
|
||||
DataPosFrac &= FRACTIONMASK;
|
||||
}
|
||||
OutPos += DstBufferSize;
|
||||
|
||||
/* Handle looping sources */
|
||||
while(1)
|
||||
@@ -770,7 +372,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
break;
|
||||
}
|
||||
|
||||
if(Looping && Source->lSourceType == AL_STATIC)
|
||||
if(Looping && Source->SourceType == AL_STATIC)
|
||||
{
|
||||
DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart;
|
||||
break;
|
||||
@@ -808,15 +410,12 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
|
||||
Source->BuffersPlayed = BuffersPlayed;
|
||||
Source->position = DataPosInt;
|
||||
Source->position_fraction = DataPosFrac;
|
||||
Source->HrtfOffset += OutPos;
|
||||
Source->Hrtf.Offset += OutPos;
|
||||
if(State == AL_PLAYING)
|
||||
{
|
||||
Source->HrtfCounter = maxu(Source->HrtfCounter, OutPos) - OutPos;
|
||||
Source->HrtfMoving = AL_TRUE;
|
||||
}
|
||||
Source->Hrtf.Counter = maxu(Source->Hrtf.Counter, OutPos) - OutPos;
|
||||
else
|
||||
{
|
||||
Source->HrtfCounter = 0;
|
||||
Source->HrtfMoving = AL_FALSE;
|
||||
Source->Hrtf.Counter = 0;
|
||||
Source->Hrtf.Moving = AL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alSource.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
|
||||
|
||||
static __inline ALfloat point32(const ALfloat *vals, ALuint frac)
|
||||
{ return vals[0]; (void)frac; }
|
||||
static __inline ALfloat lerp32(const ALfloat *vals, ALuint frac)
|
||||
{ return lerp(vals[0], vals[1], frac * (1.0f/FRACTIONONE)); }
|
||||
static __inline ALfloat cubic32(const ALfloat *vals, ALuint frac)
|
||||
{ return cubic(vals[-1], vals[0], vals[1], vals[2], frac * (1.0f/FRACTIONONE)); }
|
||||
|
||||
void Resample_copy32_C(const ALfloat *data, ALuint frac,
|
||||
ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize)
|
||||
{
|
||||
(void)frac;
|
||||
assert(increment==FRACTIONONE);
|
||||
memcpy(OutBuffer, data, (BufferSize+1)*sizeof(ALfloat));
|
||||
}
|
||||
|
||||
#define DECL_TEMPLATE(Sampler) \
|
||||
void Resample_##Sampler##_C(const ALfloat *data, ALuint frac, \
|
||||
ALuint increment, ALfloat *RESTRICT OutBuffer, ALuint BufferSize) \
|
||||
{ \
|
||||
ALuint pos = 0; \
|
||||
ALuint i; \
|
||||
\
|
||||
for(i = 0;i < BufferSize+1;i++) \
|
||||
{ \
|
||||
OutBuffer[i] = Sampler(data + pos, frac); \
|
||||
\
|
||||
frac += increment; \
|
||||
pos += frac>>FRACTIONBITS; \
|
||||
frac &= FRACTIONMASK; \
|
||||
} \
|
||||
}
|
||||
|
||||
DECL_TEMPLATE(point32)
|
||||
DECL_TEMPLATE(lerp32)
|
||||
DECL_TEMPLATE(cubic32)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
Coeffs[c][0] += CoeffStep[c][0];
|
||||
Coeffs[c][1] += CoeffStep[c][1];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
}
|
||||
}
|
||||
|
||||
#define SUFFIX C
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
|
||||
|
||||
void MixDirect_C(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
ALfloat DrySend;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
DrySend = params->Gains[srcchan][c];
|
||||
if(DrySend < 0.00001f)
|
||||
continue;
|
||||
|
||||
if(OutPos == 0)
|
||||
ClickRemoval[c] -= data[0]*DrySend;
|
||||
for(pos = 0;pos < BufferSize;pos++)
|
||||
DryBuffer[c][OutPos+pos] += data[pos]*DrySend;
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
PendingClicks[c] += data[pos]*DrySend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MixSend_C(const SendParams *params, const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALeffectslot *Slot = params->Slot;
|
||||
ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer;
|
||||
ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval;
|
||||
ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks;
|
||||
ALfloat WetSend = params->Gain;
|
||||
ALuint pos;
|
||||
|
||||
if(WetSend < 0.00001f)
|
||||
return;
|
||||
|
||||
if(OutPos == 0)
|
||||
WetClickRemoval[0] -= data[0] * WetSend;
|
||||
for(pos = 0;pos < BufferSize;pos++)
|
||||
WetBuffer[0][OutPos+pos] += data[pos] * WetSend;
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
WetPendingClicks[0] += data[pos] * WetSend;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef MIXER_DEFS_H
|
||||
#define MIXER_DEFS_H
|
||||
|
||||
#include "AL/alc.h"
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
struct DirectParams;
|
||||
struct SendParams;
|
||||
|
||||
/* C resamplers */
|
||||
void Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
void Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
|
||||
|
||||
/* C mixers */
|
||||
void MixDirect_Hrtf_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixDirect_C(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixSend_C(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
|
||||
|
||||
/* SSE mixers */
|
||||
void MixDirect_Hrtf_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixDirect_SSE(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
void MixSend_SSE(const struct SendParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint);
|
||||
|
||||
/* Neon mixers */
|
||||
void MixDirect_Hrtf_Neon(const struct DirectParams*,const ALfloat*RESTRICT,ALuint,ALuint,ALuint,ALuint);
|
||||
|
||||
#endif /* MIXER_DEFS_H */
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "alMain.h"
|
||||
#include "alSource.h"
|
||||
#include "mixer_defs.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
#define UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
#define LIKELY(x) (x)
|
||||
#define UNLIKELY(x) (x)
|
||||
#endif
|
||||
|
||||
#define REAL_MERGE2(a,b) a##b
|
||||
#define MERGE2(a,b) REAL_MERGE2(a,b)
|
||||
|
||||
#define MixDirect_Hrtf MERGE2(MixDirect_Hrtf_,SUFFIX)
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint irSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right);
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint irSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right);
|
||||
|
||||
|
||||
void MixDirect_Hrtf(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
const ALuint IrSize = params->Hrtf.Params.IrSize;
|
||||
const ALint *RESTRICT DelayStep = params->Hrtf.Params.DelayStep;
|
||||
const ALfloat (*RESTRICT CoeffStep)[2] = params->Hrtf.Params.CoeffStep;
|
||||
const ALfloat (*RESTRICT TargetCoeffs)[2] = params->Hrtf.Params.Coeffs[srcchan];
|
||||
const ALuint *RESTRICT TargetDelay = params->Hrtf.Params.Delay[srcchan];
|
||||
ALfloat *RESTRICT History = params->Hrtf.State->History[srcchan];
|
||||
ALfloat (*RESTRICT Values)[2] = params->Hrtf.State->Values[srcchan];
|
||||
ALint Counter = maxu(params->Hrtf.State->Counter, OutPos) - OutPos;
|
||||
ALuint Offset = params->Hrtf.State->Offset + OutPos;
|
||||
ALIGN(16) ALfloat Coeffs[HRIR_LENGTH][2];
|
||||
ALuint Delay[2];
|
||||
ALfloat left, right;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
pos = 0;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
Coeffs[c][0] = TargetCoeffs[c][0] - (CoeffStep[c][0]*Counter);
|
||||
Coeffs[c][1] = TargetCoeffs[c][1] - (CoeffStep[c][1]*Counter);
|
||||
}
|
||||
|
||||
Delay[0] = TargetDelay[0] - (DelayStep[0]*Counter);
|
||||
Delay[1] = TargetDelay[1] - (DelayStep[1]*Counter);
|
||||
|
||||
if(LIKELY(OutPos == 0))
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
|
||||
ClickRemoval[FrontLeft] -= Values[(Offset+1)&HRIR_MASK][0] +
|
||||
Coeffs[0][0] * left;
|
||||
ClickRemoval[FrontRight] -= Values[(Offset+1)&HRIR_MASK][1] +
|
||||
Coeffs[0][1] * right;
|
||||
}
|
||||
for(pos = 0;pos < BufferSize && Counter > 0;pos++)
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = lerp(History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
right = lerp(History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK],
|
||||
History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK],
|
||||
(Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE));
|
||||
|
||||
Delay[0] += DelayStep[0];
|
||||
Delay[1] += DelayStep[1];
|
||||
|
||||
Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
|
||||
Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
|
||||
Offset++;
|
||||
|
||||
ApplyCoeffsStep(Offset, Values, IrSize, Coeffs, CoeffStep, left, right);
|
||||
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
|
||||
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
|
||||
|
||||
OutPos++;
|
||||
Counter--;
|
||||
}
|
||||
|
||||
Delay[0] >>= HRTFDELAY_BITS;
|
||||
Delay[1] >>= HRTFDELAY_BITS;
|
||||
for(;pos < BufferSize;pos++)
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
|
||||
|
||||
Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f;
|
||||
Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f;
|
||||
Offset++;
|
||||
|
||||
ApplyCoeffs(Offset, Values, IrSize, Coeffs, left, right);
|
||||
DryBuffer[FrontLeft][OutPos] += Values[Offset&HRIR_MASK][0];
|
||||
DryBuffer[FrontRight][OutPos] += Values[Offset&HRIR_MASK][1];
|
||||
|
||||
OutPos++;
|
||||
}
|
||||
if(LIKELY(OutPos == SamplesToDo))
|
||||
{
|
||||
History[Offset&SRC_HISTORY_MASK] = data[pos];
|
||||
left = History[(Offset-Delay[0])&SRC_HISTORY_MASK];
|
||||
right = History[(Offset-Delay[1])&SRC_HISTORY_MASK];
|
||||
|
||||
PendingClicks[FrontLeft] += Values[(Offset+1)&HRIR_MASK][0] +
|
||||
Coeffs[0][0] * left;
|
||||
PendingClicks[FrontRight] += Values[(Offset+1)&HRIR_MASK][1] +
|
||||
Coeffs[0][1] * right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#undef MixDirect_Hrtf
|
||||
|
||||
#undef MERGE2
|
||||
#undef REAL_MERGE2
|
||||
|
||||
#undef UNLIKELY
|
||||
#undef LIKELY
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_ARM_NEON_H
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
for(c = 0;c < IrSize;c++)
|
||||
{
|
||||
const ALuint off = (Offset+c)&HRIR_MASK;
|
||||
Values[off][0] += Coeffs[c][0] * left;
|
||||
Values[off][1] += Coeffs[c][1] * right;
|
||||
Coeffs[c][0] += CoeffStep[c][0];
|
||||
Coeffs[c][1] += CoeffStep[c][1];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
ALuint c;
|
||||
float32x4_t leftright4;
|
||||
{
|
||||
float32x2_t leftright2 = vdup_n_f32(0.0);
|
||||
leftright2 = vset_lane_f32(left, leftright2, 0);
|
||||
leftright2 = vset_lane_f32(right, leftright2, 1);
|
||||
leftright4 = vcombine_f32(leftright2, leftright2);
|
||||
}
|
||||
for(c = 0;c < IrSize;c += 2)
|
||||
{
|
||||
const ALuint o0 = (Offset+c)&HRIR_MASK;
|
||||
const ALuint o1 = (o0+1)&HRIR_MASK;
|
||||
float32x4_t vals = vcombine_f32(vld1_f32((float32_t*)&Values[o0][0]),
|
||||
vld1_f32((float32_t*)&Values[o1][0]));
|
||||
float32x4_t coefs = vld1q_f32((float32_t*)&Coeffs[c][0]);
|
||||
|
||||
vals = vmlaq_f32(vals, coefs, leftright4);
|
||||
|
||||
vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals));
|
||||
vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SUFFIX Neon
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_XMMINTRIN_H
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
|
||||
#include "alSource.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "mixer_defs.h"
|
||||
|
||||
|
||||
static __inline void ApplyCoeffsStep(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
const ALfloat (*RESTRICT CoeffStep)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
const __m128 lrlr = { left, right, left, right };
|
||||
__m128 coeffs, deltas, imp0, imp1;
|
||||
__m128 vals = _mm_setzero_ps();
|
||||
ALuint i;
|
||||
|
||||
if((Offset&1))
|
||||
{
|
||||
const ALuint o0 = Offset&HRIR_MASK;
|
||||
const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[0][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[0][0]);
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[0][0], coeffs);
|
||||
_mm_storel_pi((__m64*)&Values[o0][0], vals);
|
||||
for(i = 1;i < IrSize-1;i += 2)
|
||||
{
|
||||
const ALuint o2 = (Offset+i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i+1][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[i+1][0]);
|
||||
vals = _mm_load_ps(&Values[o2][0]);
|
||||
imp1 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[i+1][0], coeffs);
|
||||
_mm_store_ps(&Values[o2][0], vals);
|
||||
imp0 = imp1;
|
||||
}
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]);
|
||||
imp0 = _mm_movehl_ps(imp0, imp0);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o1][0], vals);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < IrSize;i += 2)
|
||||
{
|
||||
const ALuint o = (Offset + i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i][0]);
|
||||
deltas = _mm_load_ps(&CoeffStep[i][0]);
|
||||
vals = _mm_load_ps(&Values[o][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
coeffs = _mm_add_ps(coeffs, deltas);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Coeffs[i][0], coeffs);
|
||||
_mm_store_ps(&Values[o][0], vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void ApplyCoeffs(ALuint Offset, ALfloat (*RESTRICT Values)[2],
|
||||
const ALuint IrSize,
|
||||
ALfloat (*RESTRICT Coeffs)[2],
|
||||
ALfloat left, ALfloat right)
|
||||
{
|
||||
const __m128 lrlr = { left, right, left, right };
|
||||
__m128 vals = _mm_setzero_ps();
|
||||
__m128 coeffs;
|
||||
ALuint i;
|
||||
|
||||
if((Offset&1))
|
||||
{
|
||||
const ALuint o0 = Offset&HRIR_MASK;
|
||||
const ALuint o1 = (Offset+IrSize-1)&HRIR_MASK;
|
||||
__m128 imp0, imp1;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[0][0]);
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o0][0]);
|
||||
imp0 = _mm_mul_ps(lrlr, coeffs);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o0][0], vals);
|
||||
for(i = 1;i < IrSize-1;i += 2)
|
||||
{
|
||||
const ALuint o2 = (Offset+i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i+1][0]);
|
||||
vals = _mm_load_ps(&Values[o2][0]);
|
||||
imp1 = _mm_mul_ps(lrlr, coeffs);
|
||||
imp0 = _mm_shuffle_ps(imp0, imp1, _MM_SHUFFLE(1, 0, 3, 2));
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_store_ps(&Values[o2][0], vals);
|
||||
imp0 = imp1;
|
||||
}
|
||||
vals = _mm_loadl_pi(vals, (__m64*)&Values[o1][0]);
|
||||
imp0 = _mm_movehl_ps(imp0, imp0);
|
||||
vals = _mm_add_ps(imp0, vals);
|
||||
_mm_storel_pi((__m64*)&Values[o1][0], vals);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0;i < IrSize;i += 2)
|
||||
{
|
||||
const ALuint o = (Offset + i)&HRIR_MASK;
|
||||
|
||||
coeffs = _mm_load_ps(&Coeffs[i][0]);
|
||||
vals = _mm_load_ps(&Values[o][0]);
|
||||
vals = _mm_add_ps(vals, _mm_mul_ps(lrlr, coeffs));
|
||||
_mm_store_ps(&Values[o][0], vals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SUFFIX SSE
|
||||
#include "mixer_inc.c"
|
||||
#undef SUFFIX
|
||||
|
||||
|
||||
void MixDirect_SSE(const DirectParams *params, const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALfloat (*RESTRICT DryBuffer)[BUFFERSIZE] = params->OutBuffer;
|
||||
ALfloat *RESTRICT ClickRemoval = params->ClickRemoval;
|
||||
ALfloat *RESTRICT PendingClicks = params->PendingClicks;
|
||||
ALfloat DrySend;
|
||||
ALuint pos;
|
||||
ALuint c;
|
||||
|
||||
for(c = 0;c < MaxChannels;c++)
|
||||
{
|
||||
__m128 gain;
|
||||
|
||||
DrySend = params->Gains[srcchan][c];
|
||||
if(DrySend < 0.00001f)
|
||||
continue;
|
||||
|
||||
if(OutPos == 0)
|
||||
ClickRemoval[c] -= data[0]*DrySend;
|
||||
|
||||
gain = _mm_set1_ps(DrySend);
|
||||
for(pos = 0;pos < BufferSize-3;pos += 4)
|
||||
{
|
||||
const __m128 val4 = _mm_load_ps(&data[pos]);
|
||||
__m128 dry4 = _mm_load_ps(&DryBuffer[c][OutPos+pos]);
|
||||
dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain));
|
||||
_mm_store_ps(&DryBuffer[c][OutPos+pos], dry4);
|
||||
}
|
||||
for(;pos < BufferSize;pos++)
|
||||
DryBuffer[c][OutPos+pos] += data[pos]*DrySend;
|
||||
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
PendingClicks[c] += data[pos]*DrySend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MixSend_SSE(const SendParams *params, const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize)
|
||||
{
|
||||
ALeffectslot *Slot = params->Slot;
|
||||
ALfloat (*RESTRICT WetBuffer)[BUFFERSIZE] = Slot->WetBuffer;
|
||||
ALfloat *RESTRICT WetClickRemoval = Slot->ClickRemoval;
|
||||
ALfloat *RESTRICT WetPendingClicks = Slot->PendingClicks;
|
||||
const ALfloat WetGain = params->Gain;
|
||||
__m128 gain;
|
||||
ALuint pos;
|
||||
|
||||
if(WetGain < 0.00001f)
|
||||
return;
|
||||
|
||||
if(OutPos == 0)
|
||||
WetClickRemoval[0] -= data[0] * WetGain;
|
||||
|
||||
gain = _mm_set1_ps(WetGain);
|
||||
for(pos = 0;pos < BufferSize-3;pos+=4)
|
||||
{
|
||||
const __m128 val4 = _mm_load_ps(&data[pos]);
|
||||
__m128 wet4 = _mm_load_ps(&WetBuffer[0][OutPos+pos]);
|
||||
wet4 = _mm_add_ps(wet4, _mm_mul_ps(val4, gain));
|
||||
_mm_store_ps(&WetBuffer[0][OutPos+pos], wet4);
|
||||
}
|
||||
for(;pos < BufferSize;pos++)
|
||||
WetBuffer[0][OutPos+pos] += data[pos] * WetGain;
|
||||
|
||||
if(OutPos+pos == SamplesToDo)
|
||||
WetPendingClicks[0] += data[pos] * WetGain;
|
||||
}
|
||||
+239
-107
@@ -31,8 +31,8 @@
|
||||
#include "AL/alc.h"
|
||||
#include "alu.h"
|
||||
|
||||
static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHANNELS],
|
||||
enum Channel Speaker2Chan[MAXCHANNELS], ALint chans)
|
||||
static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MaxChannels],
|
||||
enum Channel Speaker2Chan[MaxChannels], ALint chans)
|
||||
{
|
||||
char *confkey, *next;
|
||||
char *layout_str;
|
||||
@@ -71,21 +71,21 @@ static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHAN
|
||||
*(++end) = 0;
|
||||
|
||||
if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0)
|
||||
val = FRONT_LEFT;
|
||||
val = FrontLeft;
|
||||
else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0)
|
||||
val = FRONT_RIGHT;
|
||||
val = FrontRight;
|
||||
else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0)
|
||||
val = FRONT_CENTER;
|
||||
val = FrontCenter;
|
||||
else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0)
|
||||
val = BACK_LEFT;
|
||||
val = BackLeft;
|
||||
else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0)
|
||||
val = BACK_RIGHT;
|
||||
val = BackRight;
|
||||
else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0)
|
||||
val = BACK_CENTER;
|
||||
val = BackCenter;
|
||||
else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0)
|
||||
val = SIDE_LEFT;
|
||||
val = SideLeft;
|
||||
else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0)
|
||||
val = SIDE_RIGHT;
|
||||
val = SideRight;
|
||||
else
|
||||
{
|
||||
ERR("Unknown speaker for %s: \"%s\"\n", name, confkey);
|
||||
@@ -139,54 +139,228 @@ static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MAXCHAN
|
||||
}
|
||||
}
|
||||
|
||||
static ALfloat aluLUTpos2Angle(ALint pos)
|
||||
|
||||
/**
|
||||
* ComputeAngleGains
|
||||
*
|
||||
* Sets channel gains based on a given source's angle and its half-width. The
|
||||
* angle and hwidth parameters are in radians.
|
||||
*/
|
||||
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains)
|
||||
{
|
||||
if(pos < QUADRANT_NUM)
|
||||
return aluAtan((ALfloat)pos / (ALfloat)(QUADRANT_NUM - pos));
|
||||
if(pos < 2 * QUADRANT_NUM)
|
||||
return F_PI_2 + aluAtan((ALfloat)(pos - QUADRANT_NUM) / (ALfloat)(2 * QUADRANT_NUM - pos));
|
||||
if(pos < 3 * QUADRANT_NUM)
|
||||
return aluAtan((ALfloat)(pos - 2 * QUADRANT_NUM) / (ALfloat)(3 * QUADRANT_NUM - pos)) - F_PI;
|
||||
return aluAtan((ALfloat)(pos - 3 * QUADRANT_NUM) / (ALfloat)(4 * QUADRANT_NUM - pos)) - F_PI_2;
|
||||
ALfloat tmpgains[MaxChannels] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
enum Channel Speaker2Chan[MaxChannels];
|
||||
ALfloat SpeakerAngle[MaxChannels];
|
||||
ALfloat langle, rangle;
|
||||
ALfloat a;
|
||||
ALuint i;
|
||||
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
Speaker2Chan[i] = device->Speaker2Chan[i];
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
SpeakerAngle[i] = device->SpeakerAngle[i];
|
||||
|
||||
/* Some easy special-cases first... */
|
||||
if(device->NumChan == 1 || hwidth >= F_PI)
|
||||
{
|
||||
/* Full coverage for all speakers. */
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
gains[chan] = ingain;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(hwidth <= 0.0f)
|
||||
{
|
||||
/* Infinitely small sound point. */
|
||||
for(i = 0;i < device->NumChan-1;i++)
|
||||
{
|
||||
if(angle >= SpeakerAngle[i] && angle < SpeakerAngle[i+1])
|
||||
{
|
||||
/* Sound is between speakers i and i+1 */
|
||||
a = (angle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
|
||||
gains[Speaker2Chan[i+1]] = sqrtf( a) * ingain;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Sound is between last and first speakers */
|
||||
if(angle < SpeakerAngle[0])
|
||||
angle += F_PI*2.0f;
|
||||
a = (angle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
gains[Speaker2Chan[i]] = sqrtf(1.0f-a) * ingain;
|
||||
gains[Speaker2Chan[0]] = sqrtf( a) * ingain;
|
||||
return;
|
||||
}
|
||||
|
||||
if(fabsf(angle)+hwidth > F_PI)
|
||||
{
|
||||
/* The coverage area would go outside of -pi...+pi. Instead, rotate the
|
||||
* speaker angles so it would be as if angle=0, and keep them wrapped
|
||||
* within -pi...+pi. */
|
||||
if(angle > 0.0f)
|
||||
{
|
||||
ALuint done = 0;
|
||||
ALuint i = 0;
|
||||
while(i < device->NumChan && device->SpeakerAngle[i]-angle < -F_PI)
|
||||
i++;
|
||||
for(done = 0;i < device->NumChan;done++)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
i++;
|
||||
}
|
||||
for(i = 0;done < device->NumChan;i++)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle + F_PI*2.0f;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
done++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NOTE: '< device->NumChan' on the iterators is correct here since
|
||||
* we need to handle index 0. Because the iterators are unsigned,
|
||||
* they'll underflow and wrap to become 0xFFFFFFFF, which will
|
||||
* break as expected. */
|
||||
ALuint done = device->NumChan-1;
|
||||
ALuint i = device->NumChan-1;
|
||||
while(i < device->NumChan && device->SpeakerAngle[i]-angle > F_PI)
|
||||
i--;
|
||||
for(done = device->NumChan-1;i < device->NumChan;done--)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
i--;
|
||||
}
|
||||
for(i = device->NumChan-1;done < device->NumChan;i--)
|
||||
{
|
||||
SpeakerAngle[done] = device->SpeakerAngle[i]-angle - F_PI*2.0f;
|
||||
Speaker2Chan[done] = device->Speaker2Chan[i];
|
||||
done--;
|
||||
}
|
||||
}
|
||||
angle = 0.0f;
|
||||
}
|
||||
langle = angle - hwidth;
|
||||
rangle = angle + hwidth;
|
||||
|
||||
/* First speaker */
|
||||
i = 0;
|
||||
do {
|
||||
ALuint last = device->NumChan-1;
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[chan] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle)
|
||||
{
|
||||
a = (F_PI*2.0f + rangle-SpeakerAngle[last]) /
|
||||
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
else if(SpeakerAngle[last] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[last]) /
|
||||
(F_PI*2.0f + SpeakerAngle[i]-SpeakerAngle[last]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
for(i = 1;i < device->NumChan-1;i++)
|
||||
{
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[chan] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(SpeakerAngle[i] < langle && SpeakerAngle[i+1] > langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(SpeakerAngle[i+1]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[i-1]) /
|
||||
(SpeakerAngle[i]-SpeakerAngle[i-1]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
}
|
||||
|
||||
/* Last speaker */
|
||||
i = device->NumChan-1;
|
||||
do {
|
||||
enum Channel chan = Speaker2Chan[i];
|
||||
if(SpeakerAngle[i] >= langle && SpeakerAngle[i] <= rangle)
|
||||
{
|
||||
tmpgains[Speaker2Chan[i]] = 1.0f;
|
||||
continue;
|
||||
}
|
||||
if(SpeakerAngle[i] > rangle && SpeakerAngle[i-1] < rangle)
|
||||
{
|
||||
a = (rangle-SpeakerAngle[i-1]) /
|
||||
(SpeakerAngle[i]-SpeakerAngle[i-1]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a);
|
||||
}
|
||||
if(SpeakerAngle[i] < langle)
|
||||
{
|
||||
a = (langle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
else if(SpeakerAngle[0] > langle)
|
||||
{
|
||||
a = (F_PI*2.0f + langle-SpeakerAngle[i]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[i]);
|
||||
tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a);
|
||||
}
|
||||
} while(0);
|
||||
|
||||
for(i = 0;i < device->NumChan;i++)
|
||||
{
|
||||
enum Channel chan = device->Speaker2Chan[i];
|
||||
gains[chan] = sqrtf(tmpgains[chan]) * ingain;
|
||||
}
|
||||
}
|
||||
|
||||
ALint aluCart2LUTpos(ALfloat re, ALfloat im)
|
||||
{
|
||||
ALint pos = 0;
|
||||
ALfloat denom = aluFabs(re) + aluFabs(im);
|
||||
if(denom > 0.0f)
|
||||
pos = (ALint)(QUADRANT_NUM*aluFabs(im) / denom + 0.5);
|
||||
|
||||
if(re < 0.0f)
|
||||
pos = 2 * QUADRANT_NUM - pos;
|
||||
if(im < 0.0f)
|
||||
pos = LUT_NUM - pos;
|
||||
return pos%LUT_NUM;
|
||||
}
|
||||
|
||||
ALvoid aluInitPanning(ALCdevice *Device)
|
||||
{
|
||||
ALfloat SpeakerAngle[MAXCHANNELS];
|
||||
const char *layoutname = NULL;
|
||||
enum Channel *Speaker2Chan;
|
||||
ALfloat Alpha, Theta;
|
||||
ALint pos;
|
||||
ALuint s;
|
||||
ALfloat *SpeakerAngle;
|
||||
|
||||
Speaker2Chan = Device->Speaker2Chan;
|
||||
SpeakerAngle = Device->SpeakerAngle;
|
||||
switch(Device->FmtChans)
|
||||
{
|
||||
case DevFmtMono:
|
||||
Device->NumChan = 1;
|
||||
Speaker2Chan[0] = FRONT_CENTER;
|
||||
Speaker2Chan[0] = FrontCenter;
|
||||
SpeakerAngle[0] = F_PI/180.0f * 0.0f;
|
||||
layoutname = NULL;
|
||||
break;
|
||||
|
||||
case DevFmtStereo:
|
||||
Device->NumChan = 2;
|
||||
Speaker2Chan[0] = FRONT_LEFT;
|
||||
Speaker2Chan[1] = FRONT_RIGHT;
|
||||
Speaker2Chan[0] = FrontLeft;
|
||||
Speaker2Chan[1] = FrontRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * 90.0f;
|
||||
layoutname = "layout_stereo";
|
||||
@@ -194,10 +368,10 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
|
||||
case DevFmtQuad:
|
||||
Device->NumChan = 4;
|
||||
Speaker2Chan[0] = BACK_LEFT;
|
||||
Speaker2Chan[1] = FRONT_LEFT;
|
||||
Speaker2Chan[2] = FRONT_RIGHT;
|
||||
Speaker2Chan[3] = BACK_RIGHT;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontRight;
|
||||
Speaker2Chan[3] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -135.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -45.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 45.0f;
|
||||
@@ -207,11 +381,11 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
|
||||
case DevFmtX51:
|
||||
Device->NumChan = 5;
|
||||
Speaker2Chan[0] = BACK_LEFT;
|
||||
Speaker2Chan[1] = FRONT_LEFT;
|
||||
Speaker2Chan[2] = FRONT_CENTER;
|
||||
Speaker2Chan[3] = FRONT_RIGHT;
|
||||
Speaker2Chan[4] = BACK_RIGHT;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -110.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
@@ -222,11 +396,11 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
|
||||
case DevFmtX51Side:
|
||||
Device->NumChan = 5;
|
||||
Speaker2Chan[0] = SIDE_LEFT;
|
||||
Speaker2Chan[1] = FRONT_LEFT;
|
||||
Speaker2Chan[2] = FRONT_CENTER;
|
||||
Speaker2Chan[3] = FRONT_RIGHT;
|
||||
Speaker2Chan[4] = SIDE_RIGHT;
|
||||
Speaker2Chan[0] = SideLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = SideRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
@@ -237,12 +411,12 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
|
||||
case DevFmtX61:
|
||||
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;
|
||||
Speaker2Chan[0] = SideLeft;
|
||||
Speaker2Chan[1] = FrontLeft;
|
||||
Speaker2Chan[2] = FrontCenter;
|
||||
Speaker2Chan[3] = FrontRight;
|
||||
Speaker2Chan[4] = SideRight;
|
||||
Speaker2Chan[5] = BackCenter;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -30.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * 0.0f;
|
||||
@@ -254,13 +428,13 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
|
||||
case DevFmtX71:
|
||||
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;
|
||||
Speaker2Chan[0] = BackLeft;
|
||||
Speaker2Chan[1] = SideLeft;
|
||||
Speaker2Chan[2] = FrontLeft;
|
||||
Speaker2Chan[3] = FrontCenter;
|
||||
Speaker2Chan[4] = FrontRight;
|
||||
Speaker2Chan[5] = SideRight;
|
||||
Speaker2Chan[6] = BackRight;
|
||||
SpeakerAngle[0] = F_PI/180.0f * -150.0f;
|
||||
SpeakerAngle[1] = F_PI/180.0f * -90.0f;
|
||||
SpeakerAngle[2] = F_PI/180.0f * -30.0f;
|
||||
@@ -273,46 +447,4 @@ ALvoid aluInitPanning(ALCdevice *Device)
|
||||
}
|
||||
if(layoutname && Device->Type != Loopback)
|
||||
SetSpeakerArrangement(layoutname, SpeakerAngle, Speaker2Chan, Device->NumChan);
|
||||
|
||||
for(pos = 0; pos < LUT_NUM; pos++)
|
||||
{
|
||||
ALfloat *PanningLUT = Device->PanningLUT[pos];
|
||||
|
||||
/* clear all values */
|
||||
for(s = 0; s < MAXCHANNELS; s++)
|
||||
PanningLUT[s] = 0.0f;
|
||||
|
||||
if(Device->NumChan == 1)
|
||||
{
|
||||
PanningLUT[Speaker2Chan[0]] = 1.0f;
|
||||
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 = (Theta-SpeakerAngle[s]) /
|
||||
(SpeakerAngle[s+1]-SpeakerAngle[s]);
|
||||
PanningLUT[Speaker2Chan[s]] = aluSqrt(1.0f-Alpha);
|
||||
PanningLUT[Speaker2Chan[s+1]] = aluSqrt( Alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(s == Device->NumChan - 1)
|
||||
{
|
||||
/* source between last and first speaker */
|
||||
if(Theta < SpeakerAngle[0])
|
||||
Theta += F_PI*2.0f;
|
||||
Alpha = (Theta-SpeakerAngle[s]) /
|
||||
(F_PI*2.0f + SpeakerAngle[0]-SpeakerAngle[s]);
|
||||
PanningLUT[Speaker2Chan[s]] = aluSqrt(1.0f-Alpha);
|
||||
PanningLUT[Speaker2Chan[0]] = aluSqrt( Alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+111
-35
@@ -26,6 +26,13 @@ PROJECT(OpenAL C)
|
||||
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE)
|
||||
|
||||
|
||||
OPTION(SSE "Check for SSE CPU extensions" ON)
|
||||
OPTION(NEON "Check for ARM Neon CPU extensions" ON)
|
||||
|
||||
OPTION(REQUIRE_SSE "Require SSE CPU extensions" OFF)
|
||||
OPTION(REQUIRE_NEON "Require ARM Neon CPU extensions" OFF)
|
||||
|
||||
|
||||
OPTION(ALSA "Check for ALSA backend" ON)
|
||||
OPTION(OSS "Check for OSS backend" ON)
|
||||
OPTION(SOLARIS "Check for Solaris backend" ON)
|
||||
@@ -59,7 +66,7 @@ OPTION(UTILS "Build and install utility programs" ON)
|
||||
|
||||
OPTION(EXAMPLES "Build and install example programs" ON)
|
||||
|
||||
OPTION(ALSOFT_CONFIG "Install alsoft.conf configuration file" OFF)
|
||||
OPTION(ALSOFT_CONFIG "Install alsoft.conf sample configuration file" ON)
|
||||
|
||||
|
||||
IF(WIN32)
|
||||
@@ -74,10 +81,12 @@ IF(NOT LIBTYPE)
|
||||
ENDIF()
|
||||
|
||||
SET(LIB_MAJOR_VERSION "1")
|
||||
SET(LIB_MINOR_VERSION "14")
|
||||
SET(LIB_MINOR_VERSION "15")
|
||||
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}")
|
||||
|
||||
SET(EXPORT_DECL "")
|
||||
SET(ALIGN_DECL "")
|
||||
SET(RESTRICT_DECL "")
|
||||
|
||||
|
||||
CHECK_TYPE_SIZE("long" SIZEOF_LONG)
|
||||
@@ -86,8 +95,15 @@ CHECK_TYPE_SIZE("long long" SIZEOF_LONG_LONG)
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int *restrict foo;
|
||||
int main() {return 0;}" HAVE_RESTRICT)
|
||||
CHECK_C_SOURCE_COMPILES("int *__restrict foo;
|
||||
int main() {return 0;}" HAVE___RESTRICT)
|
||||
IF(HAVE_RESTRICT)
|
||||
SET(RESTRICT_DECL "restrict")
|
||||
ELSE()
|
||||
CHECK_C_SOURCE_COMPILES("int *__restrict foo;
|
||||
int main() {return 0;}" HAVE___RESTRICT)
|
||||
IF(HAVE___RESTRICT)
|
||||
SET(RESTRICT_DECL "__restrict")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
# Add definitions, compiler switches, etc.
|
||||
@@ -166,6 +182,7 @@ ENDIF()
|
||||
# Set visibility/export options if available
|
||||
IF(WIN32)
|
||||
SET(EXPORT_DECL "__declspec(dllexport)")
|
||||
SET(ALIGN_DECL "__declspec(align(x))")
|
||||
|
||||
OPTION(WINE "Enable use of Wine headers when compiling" OFF)
|
||||
IF(WINE)
|
||||
@@ -211,21 +228,33 @@ ELSE()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int foo __attribute__((aligned(16)));
|
||||
int main() {return 0;}" HAVE_ATTRIBUTE_ALIGNED)
|
||||
IF(HAVE_ATTRIBUTE_ALIGNED)
|
||||
SET(ALIGN_DECL "__attribute__((aligned(x)))")
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}")
|
||||
ENDIF()
|
||||
|
||||
SET(SSE_SWITCH "")
|
||||
CHECK_C_COMPILER_FLAG(-msse HAVE_MSSE_SWITCH)
|
||||
IF(HAVE_MSSE_SWITCH)
|
||||
SET(SSE_SWITCH "-msse")
|
||||
ENDIF()
|
||||
|
||||
CHECK_C_SOURCE_COMPILES("int foo(const char *str, ...) __attribute__((format(printf, 1, 2)));
|
||||
int main() {return 0;}" HAVE_GCC_FORMAT)
|
||||
|
||||
CHECK_INCLUDE_FILE(malloc.h HAVE_MALLOC_H)
|
||||
CHECK_INCLUDE_FILE(cpuid.h HAVE_CPUID_H)
|
||||
CHECK_INCLUDE_FILE(fenv.h HAVE_FENV_H)
|
||||
CHECK_INCLUDE_FILE(fpu_control.h HAVE_FPU_CONTROL_H)
|
||||
CHECK_INCLUDE_FILE(float.h HAVE_FLOAT_H)
|
||||
CHECK_INCLUDE_FILE(ieeefp.h HAVE_IEEEFP_H)
|
||||
CHECK_INCLUDE_FILE(guiddef.h HAVE_GUIDDEF_H)
|
||||
IF(NOT HAVE_GUIDDEF_H)
|
||||
CHECK_INCLUDE_FILE(initguid.h HAVE_INITGUID_H)
|
||||
ENDIF()
|
||||
CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H)
|
||||
|
||||
# Some systems need libm for some of the following math functions to work
|
||||
CHECK_LIBRARY_EXISTS(m pow "" HAVE_LIBM)
|
||||
@@ -235,25 +264,20 @@ IF(HAVE_LIBM)
|
||||
ENDIF()
|
||||
|
||||
|
||||
CHECK_SYMBOL_EXISTS(powf math.h HAVE_POWF)
|
||||
CHECK_SYMBOL_EXISTS(sqrtf math.h HAVE_SQRTF)
|
||||
CHECK_SYMBOL_EXISTS(cosf math.h HAVE_COSF)
|
||||
CHECK_SYMBOL_EXISTS(sinf math.h HAVE_SINF)
|
||||
CHECK_SYMBOL_EXISTS(acosf math.h HAVE_ACOSF)
|
||||
CHECK_SYMBOL_EXISTS(asinf math.h HAVE_ASINF)
|
||||
CHECK_SYMBOL_EXISTS(atanf math.h HAVE_ATANF)
|
||||
CHECK_SYMBOL_EXISTS(atan2f math.h HAVE_ATAN2F)
|
||||
CHECK_SYMBOL_EXISTS(fabsf math.h HAVE_FABSF)
|
||||
CHECK_SYMBOL_EXISTS(log10f math.h HAVE_LOG10F)
|
||||
CHECK_SYMBOL_EXISTS(floorf math.h HAVE_FLOORF)
|
||||
CHECK_SYMBOL_EXISTS(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC)
|
||||
CHECK_SYMBOL_EXISTS(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN)
|
||||
CHECK_SYMBOL_EXISTS(_aligned_malloc malloc.h HAVE__ALIGNED_MALLOC)
|
||||
CHECK_SYMBOL_EXISTS(lrintf math.h HAVE_LRINTF)
|
||||
|
||||
IF(HAVE_FENV_H)
|
||||
CHECK_SYMBOL_EXISTS(fesetround fenv.h HAVE_FESETROUND)
|
||||
ENDIF()
|
||||
IF(HAVE_FLOAT_H)
|
||||
CHECK_SYMBOL_EXISTS(_controlfp float.h HAVE__CONTROLFP)
|
||||
CHECK_SYMBOL_EXISTS(__control87_2 float.h HAVE___CONTROL87_2)
|
||||
ENDIF()
|
||||
|
||||
CHECK_FUNCTION_EXISTS(strtof HAVE_STRTOF)
|
||||
CHECK_FUNCTION_EXISTS(_controlfp HAVE__CONTROLFP)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(stat HAVE_STAT)
|
||||
CHECK_FUNCTION_EXISTS(strcasecmp HAVE_STRCASECMP)
|
||||
IF(NOT HAVE_STRCASECMP)
|
||||
@@ -358,8 +382,7 @@ IF(NOT HAVE_WINDOWS_H)
|
||||
# Some systems need pthread_np.h to get recursive mutexes
|
||||
CHECK_INCLUDE_FILES("pthread.h;pthread_np.h" HAVE_PTHREAD_NP_H)
|
||||
|
||||
# _GNU_SOURCE is needed on some systems for extra attributes, and
|
||||
# _REENTRANT is needed for libc thread-safety
|
||||
# _GNU_SOURCE is needed on some systems for extra attributes
|
||||
ADD_DEFINITIONS(-D_GNU_SOURCE=1)
|
||||
CHECK_LIBRARY_EXISTS(pthread pthread_create "" HAVE_LIBPTHREAD)
|
||||
IF(HAVE_LIBPTHREAD)
|
||||
@@ -422,9 +445,49 @@ SET(ALC_OBJS Alc/ALc.c
|
||||
Alc/alcThread.c
|
||||
Alc/bs2b.c
|
||||
Alc/helpers.c
|
||||
Alc/panning.c
|
||||
Alc/hrtf.c
|
||||
Alc/mixer.c
|
||||
Alc/panning.c
|
||||
Alc/mixer_c.c
|
||||
)
|
||||
|
||||
|
||||
SET(CPU_EXTS "Default")
|
||||
SET(HAVE_SSE 0)
|
||||
SET(HAVE_NEON 0)
|
||||
|
||||
# Check for SSE support
|
||||
IF(SSE AND ALIGN_DECL)
|
||||
CHECK_INCLUDE_FILE(xmmintrin.h HAVE_XMMINTRIN_H "${SSE_SWITCH}")
|
||||
IF(HAVE_XMMINTRIN_H)
|
||||
SET(HAVE_SSE 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_sse.c)
|
||||
IF(SSE_SWITCH)
|
||||
SET_SOURCE_FILES_PROPERTIES(Alc/mixer_sse.c PROPERTIES
|
||||
COMPILE_FLAGS "${SSE_SWITCH}")
|
||||
ENDIF()
|
||||
SET(CPU_EXTS "${CPU_EXTS}, SSE")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_SSE AND NOT HAVE_SSE)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required SSE CPU extensions")
|
||||
ENDIF()
|
||||
|
||||
# Check for ARM Neon support
|
||||
IF(NEON)
|
||||
CHECK_INCLUDE_FILE(arm_neon.h HAVE_ARM_NEON_H)
|
||||
IF(HAVE_ARM_NEON_H)
|
||||
SET(HAVE_NEON 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/mixer_neon.c)
|
||||
SET(CPU_EXTS "${CPU_EXTS}, Neon")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(REQUIRE_NEON AND NOT HAVE_NEON)
|
||||
MESSAGE(FATAL_ERROR "Failed to enabled required ARM Neon CPU extensions")
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(ALC_OBJS ${ALC_OBJS}
|
||||
# Default backends, always available
|
||||
Alc/backends/loopback.c
|
||||
Alc/backends/null.c
|
||||
@@ -496,15 +559,11 @@ IF(SNDIO)
|
||||
CHECK_INCLUDE_FILE(sndio.h HAVE_SNDIO_H)
|
||||
IF(HAVE_SNDIO_H)
|
||||
CHECK_SHARED_FUNCTION_EXISTS(sio_open "sndio.h" sndio "" HAVE_LIBSNDIO)
|
||||
IF(HAVE_LIBSNDIO OR HAVE_DLFCN_H OR WIN32)
|
||||
IF(HAVE_LIBSNDIO)
|
||||
SET(HAVE_SNDIO 1)
|
||||
SET(ALC_OBJS ${ALC_OBJS} Alc/backends/sndio.c)
|
||||
IF(HAVE_DLFCN_H OR WIN32)
|
||||
SET(BACKENDS "${BACKENDS} SndIO,")
|
||||
ELSE()
|
||||
SET(BACKENDS "${BACKENDS} SndIO \(linked\),")
|
||||
SET(EXTRA_LIBS sndio ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
SET(BACKENDS "${BACKENDS} SndIO \(linked\),")
|
||||
SET(EXTRA_LIBS sndio ${EXTRA_LIBS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
@@ -663,7 +722,7 @@ SET(BACKENDS "${BACKENDS} Null")
|
||||
|
||||
IF(EXAMPLES)
|
||||
# Might be able to use earlier versions, but these definitely work
|
||||
PKG_CHECK_MODULES(FFMPEG libavcodec>=52.123.0 libavformat>=52.111.0)
|
||||
PKG_CHECK_MODULES(FFMPEG libavcodec>=53.61.100 libavformat>=53.32.100 libavutil>=51.35.100)
|
||||
ENDIF()
|
||||
|
||||
IF(LIBTYPE STREQUAL "STATIC")
|
||||
@@ -722,6 +781,9 @@ MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Building OpenAL with support for the following backends:")
|
||||
MESSAGE(STATUS " ${BACKENDS}")
|
||||
MESSAGE(STATUS "")
|
||||
MESSAGE(STATUS "Building with support for CPU extensions:")
|
||||
MESSAGE(STATUS " ${CPU_EXTS}")
|
||||
MESSAGE(STATUS "")
|
||||
|
||||
IF(WIN32)
|
||||
IF(NOT HAVE_DSOUND)
|
||||
@@ -734,10 +796,9 @@ ENDIF()
|
||||
# Install alsoft.conf configuration file
|
||||
IF(ALSOFT_CONFIG)
|
||||
INSTALL(FILES alsoftrc.sample
|
||||
DESTINATION /etc/openal
|
||||
RENAME alsoft.conf
|
||||
DESTINATION share/openal
|
||||
)
|
||||
MESSAGE(STATUS "Installing sample alsoft.conf")
|
||||
MESSAGE(STATUS "Installing sample configuration")
|
||||
MESSAGE(STATUS "")
|
||||
ENDIF()
|
||||
|
||||
@@ -761,10 +822,25 @@ ENDIF()
|
||||
|
||||
IF(EXAMPLES)
|
||||
IF(FFMPEG_FOUND)
|
||||
ADD_EXECUTABLE(alstream examples/alhelpers.c examples/alffmpeg.c examples/alstream.c)
|
||||
ADD_EXECUTABLE(alstream examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/alstream.c)
|
||||
TARGET_LINK_LIBRARIES(alstream ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(alstream PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
INSTALL(TARGETS alstream
|
||||
|
||||
ADD_EXECUTABLE(alreverb examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/alreverb.c)
|
||||
TARGET_LINK_LIBRARIES(alreverb ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(alreverb PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
|
||||
ADD_EXECUTABLE(allatency examples/common/alhelpers.c
|
||||
examples/common/alffmpeg.c
|
||||
examples/allatency.c)
|
||||
TARGET_LINK_LIBRARIES(allatency ${FFMPEG_LIBRARIES} ${LIBNAME})
|
||||
SET_TARGET_PROPERTIES(allatency PROPERTIES COMPILE_FLAGS "${FFMPEG_CFLAGS}")
|
||||
|
||||
INSTALL(TARGETS alstream alreverb allatency
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}"
|
||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
#ifndef _AL_AUXEFFECTSLOT_H_
|
||||
#define _AL_AUXEFFECTSLOT_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
#include "alEffect.h"
|
||||
#include "alFilter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALeffectState ALeffectState;
|
||||
typedef struct ALeffectState {
|
||||
ALvoid (*Destroy)(struct ALeffectState *State);
|
||||
ALboolean (*DeviceUpdate)(struct ALeffectState *State, ALCdevice *Device);
|
||||
ALvoid (*Update)(struct ALeffectState *State, ALCdevice *Device, const struct ALeffectslot *Slot);
|
||||
ALvoid (*Process)(struct ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]);
|
||||
} ALeffectState;
|
||||
|
||||
|
||||
typedef struct ALeffectslot
|
||||
{
|
||||
@@ -21,30 +26,21 @@ typedef struct ALeffectslot
|
||||
volatile ALenum NeedsUpdate;
|
||||
ALeffectState *EffectState;
|
||||
|
||||
ALfloat WetBuffer[BUFFERSIZE];
|
||||
ALIGN(16) ALfloat WetBuffer[1][BUFFERSIZE];
|
||||
|
||||
ALfloat ClickRemoval[1];
|
||||
ALfloat PendingClicks[1];
|
||||
|
||||
RefCount ref;
|
||||
|
||||
// Index to itself
|
||||
ALuint effectslot;
|
||||
|
||||
struct ALeffectslot *next;
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALeffectslot;
|
||||
|
||||
|
||||
ALenum InitEffectSlot(ALeffectslot *slot);
|
||||
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context);
|
||||
|
||||
struct ALeffectState {
|
||||
ALvoid (*Destroy)(ALeffectState *State);
|
||||
ALboolean (*DeviceUpdate)(ALeffectState *State, ALCdevice *Device);
|
||||
ALvoid (*Update)(ALeffectState *State, ALCdevice *Device, const ALeffectslot *Slot);
|
||||
ALvoid (*Process)(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS]);
|
||||
};
|
||||
|
||||
ALeffectState *NoneCreate(void);
|
||||
ALeffectState *ReverbCreate(void);
|
||||
ALeffectState *EchoCreate(void);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _AL_BUFFER_H_
|
||||
#define _AL_BUFFER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -84,12 +84,13 @@ typedef struct ALbuffer
|
||||
ALsizei LoopStart;
|
||||
ALsizei LoopEnd;
|
||||
|
||||
RefCount ref; // Number of sources using this buffer (deletion can only occur when this is 0)
|
||||
/* Number of times buffer was attached to a source (deletion can only occur when 0) */
|
||||
RefCount ref;
|
||||
|
||||
RWLock lock;
|
||||
|
||||
// Index to itself
|
||||
ALuint buffer;
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALbuffer;
|
||||
|
||||
ALvoid ReleaseALBuffers(ALCdevice *device);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _AL_EFFECT_H_
|
||||
#define _AL_EFFECT_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -85,8 +85,8 @@ typedef struct ALeffect
|
||||
void (*GetParamf)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val);
|
||||
void (*GetParamfv)(struct ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals);
|
||||
|
||||
// Index to itself
|
||||
ALuint effect;
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALeffect;
|
||||
|
||||
#define ALeffect_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#ifndef _AL_ERROR_H_
|
||||
#define _AL_ERROR_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#ifndef _AL_FILTER_H_
|
||||
#define _AL_FILTER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alu.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOWPASSFREQREF (5000)
|
||||
|
||||
typedef struct {
|
||||
ALfloat coeff;
|
||||
#ifndef _MSC_VER
|
||||
@@ -30,17 +31,6 @@ static __inline ALfloat lpFilter2P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
|
||||
return output;
|
||||
}
|
||||
static __inline ALfloat lpFilter1P(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
ALfloat *history = &iir->history[offset];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (history[0]-output)*a;
|
||||
history[0] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
@@ -53,16 +43,6 @@ static __inline ALfloat lpFilter2PC(const FILTER *iir, ALuint offset, ALfloat in
|
||||
|
||||
return output;
|
||||
}
|
||||
static __inline ALfloat lpFilter1PC(FILTER *iir, ALuint offset, ALfloat input)
|
||||
{
|
||||
const ALfloat *history = &iir->history[offset];
|
||||
ALfloat a = iir->coeff;
|
||||
ALfloat output = input;
|
||||
|
||||
output = output + (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,
|
||||
@@ -87,8 +67,8 @@ typedef struct ALfilter {
|
||||
void (*GetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val);
|
||||
void (*GetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals);
|
||||
|
||||
// Index to itself
|
||||
ALuint filter;
|
||||
/* Self ID */
|
||||
ALuint id;
|
||||
} ALfilter;
|
||||
|
||||
#define ALfilter_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v)))
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
#ifndef _AL_LISTENER_H_
|
||||
#define _AL_LISTENER_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALlistener_struct
|
||||
{
|
||||
typedef struct ALlistener {
|
||||
volatile ALfloat Position[3];
|
||||
volatile ALfloat Velocity[3];
|
||||
volatile ALfloat Forward[3];
|
||||
volatile ALfloat Up[3];
|
||||
volatile ALfloat Matrix[4][4];
|
||||
volatile ALfloat Gain;
|
||||
volatile ALfloat MetersPerUnit;
|
||||
|
||||
struct {
|
||||
ALfloat Matrix[4][4];
|
||||
ALfloat Velocity[3];
|
||||
} Params;
|
||||
} ALlistener;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+191
-74
@@ -4,15 +4,13 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FPU_CONTROL_H
|
||||
#include <fpu_control.h>
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
@@ -47,20 +45,14 @@ typedef unsigned long long ALuint64;
|
||||
typedef ptrdiff_t ALintptrEXT;
|
||||
typedef ptrdiff_t ALsizeiptrEXT;
|
||||
|
||||
#define MAKEU64(x,y) (((ALuint64)(x)<<32)|(ALuint64)(y))
|
||||
|
||||
#ifdef HAVE_GCC_FORMAT
|
||||
#define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
|
||||
#else
|
||||
#define PRINTF_STYLE(x, y)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_RESTRICT)
|
||||
#define RESTRICT restrict
|
||||
#elif defined(HAVE___RESTRICT)
|
||||
#define RESTRICT __restrict
|
||||
#else
|
||||
#define RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
static const union {
|
||||
ALuint u;
|
||||
@@ -72,6 +64,7 @@ static const union {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
typedef DWORD pthread_key_t;
|
||||
@@ -99,9 +92,6 @@ static __inline int sched_yield(void)
|
||||
#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>
|
||||
@@ -341,60 +331,47 @@ static __inline void LockUIntMapWrite(UIntMap *map)
|
||||
static __inline void UnlockUIntMapWrite(UIntMap *map)
|
||||
{ WriteUnlock(&map->lock); }
|
||||
|
||||
#include "alListener.h"
|
||||
#include "alu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE (44100)
|
||||
#define MIN_OUTPUT_RATE (8000)
|
||||
|
||||
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
|
||||
#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
|
||||
|
||||
#define LOWPASSFREQREF (5000)
|
||||
|
||||
|
||||
struct Hrtf;
|
||||
|
||||
|
||||
#define DEFAULT_OUTPUT_RATE (44100)
|
||||
#define MIN_OUTPUT_RATE (8000)
|
||||
|
||||
|
||||
// Find the next power-of-2 for non-power-of-2 numbers.
|
||||
static __inline ALuint NextPowerOf2(ALuint value)
|
||||
{
|
||||
ALuint powerOf2 = 1;
|
||||
|
||||
if(value)
|
||||
if(value > 0)
|
||||
{
|
||||
value--;
|
||||
while(value)
|
||||
{
|
||||
value >>= 1;
|
||||
powerOf2 <<= 1;
|
||||
}
|
||||
value |= value>>1;
|
||||
value |= value>>2;
|
||||
value |= value>>4;
|
||||
value |= value>>8;
|
||||
value |= value>>16;
|
||||
}
|
||||
return powerOf2;
|
||||
return value+1;
|
||||
}
|
||||
|
||||
/* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
|
||||
* mode. */
|
||||
static __inline ALint fastf2i(ALfloat f)
|
||||
{
|
||||
#ifdef HAVE_LRINTF
|
||||
return lrintf(f);
|
||||
#elif defined(_MSC_VER) && defined(_M_IX86)
|
||||
ALint i;
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
__asm fld f
|
||||
__asm fistp i
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
__asm__ __volatile__("flds %1\n\t"
|
||||
"fistpl %0\n\t"
|
||||
: "=m" (i)
|
||||
: "m" (f));
|
||||
#else
|
||||
i = (ALint)f;
|
||||
#endif
|
||||
return i;
|
||||
#else
|
||||
return (ALint)f;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
|
||||
@@ -421,6 +398,11 @@ typedef struct {
|
||||
void (*StopCapture)(ALCdevice*);
|
||||
ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
|
||||
ALCuint (*AvailableSamples)(ALCdevice*);
|
||||
|
||||
void (*Lock)(ALCdevice*);
|
||||
void (*Unlock)(ALCdevice*);
|
||||
|
||||
ALint64 (*GetLatency)(ALCdevice*);
|
||||
} BackendFuncs;
|
||||
|
||||
struct BackendInfo {
|
||||
@@ -475,6 +457,41 @@ void alc_loopback_deinit(void);
|
||||
void alc_loopback_probe(enum DevProbe type);
|
||||
|
||||
|
||||
enum DistanceModel {
|
||||
InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
|
||||
LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
|
||||
ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
|
||||
InverseDistance = AL_INVERSE_DISTANCE,
|
||||
LinearDistance = AL_LINEAR_DISTANCE,
|
||||
ExponentDistance = AL_EXPONENT_DISTANCE,
|
||||
DisableDistance = AL_NONE,
|
||||
|
||||
DefaultDistanceModel = InverseDistanceClamped
|
||||
};
|
||||
|
||||
enum Resampler {
|
||||
PointResampler,
|
||||
LinearResampler,
|
||||
CubicResampler,
|
||||
|
||||
ResamplerMax,
|
||||
};
|
||||
|
||||
enum Channel {
|
||||
FrontLeft = 0,
|
||||
FrontRight,
|
||||
FrontCenter,
|
||||
LFE,
|
||||
BackLeft,
|
||||
BackRight,
|
||||
BackCenter,
|
||||
SideLeft,
|
||||
SideRight,
|
||||
|
||||
MaxChannels,
|
||||
};
|
||||
|
||||
|
||||
/* Device formats */
|
||||
enum DevFmtType {
|
||||
DevFmtByte = ALC_BYTE_SOFT,
|
||||
@@ -524,6 +541,22 @@ enum DeviceType {
|
||||
Loopback
|
||||
};
|
||||
|
||||
|
||||
/* Size for temporary storage of buffer data, in ALfloats. Larger values need
|
||||
* more memory, 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, as well as the maximum number of samples per mixing iteration.
|
||||
*
|
||||
* The mixer requires being able to do two samplings per mixing loop. With the
|
||||
* cubic resampler (which requires 3 padding samples), this limits a 2048
|
||||
* buffer size to about 2044. This means that buffer_freq*source_pitch cannot
|
||||
* exceed device_freq*2044 for a 32-bit buffer.
|
||||
*/
|
||||
#ifndef BUFFERSIZE
|
||||
#define BUFFERSIZE 2048
|
||||
#endif
|
||||
|
||||
|
||||
struct ALCdevice_struct
|
||||
{
|
||||
volatile RefCount ref;
|
||||
@@ -539,7 +572,7 @@ struct ALCdevice_struct
|
||||
enum DevFmtChannels FmtChans;
|
||||
enum DevFmtType FmtType;
|
||||
|
||||
ALCchar *szDeviceName;
|
||||
ALCchar *DeviceName;
|
||||
|
||||
volatile ALCenum LastError;
|
||||
|
||||
@@ -571,17 +604,21 @@ struct ALCdevice_struct
|
||||
// Device flags
|
||||
ALuint Flags;
|
||||
|
||||
// Dry path buffer mix
|
||||
ALfloat DryBuffer[BUFFERSIZE][MAXCHANNELS];
|
||||
ALuint ChannelOffsets[MaxChannels];
|
||||
|
||||
enum Channel DevChannels[MAXCHANNELS];
|
||||
|
||||
enum Channel Speaker2Chan[MAXCHANNELS];
|
||||
ALfloat PanningLUT[LUT_NUM][MAXCHANNELS];
|
||||
enum Channel Speaker2Chan[MaxChannels];
|
||||
ALfloat SpeakerAngle[MaxChannels];
|
||||
ALuint NumChan;
|
||||
|
||||
ALfloat ClickRemoval[MAXCHANNELS];
|
||||
ALfloat PendingClicks[MAXCHANNELS];
|
||||
/* Temp storage used for mixing. +1 for the predictive sample. */
|
||||
ALIGN(16) ALfloat SampleData1[BUFFERSIZE+1];
|
||||
ALIGN(16) ALfloat SampleData2[BUFFERSIZE+1];
|
||||
|
||||
// Dry path buffer mix
|
||||
ALIGN(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE];
|
||||
|
||||
ALIGN(16) ALfloat ClickRemoval[MaxChannels];
|
||||
ALIGN(16) ALfloat PendingClicks[MaxChannels];
|
||||
|
||||
/* Default effect slot */
|
||||
struct ALeffectslot *DefaultSlot;
|
||||
@@ -606,9 +643,10 @@ struct ALCdevice_struct
|
||||
#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)))
|
||||
#define ALCdevice_Lock(a) ((a)->Funcs->Lock((a)))
|
||||
#define ALCdevice_Unlock(a) ((a)->Funcs->Unlock((a)))
|
||||
#define ALCdevice_GetLatency(a) ((a)->Funcs->GetLatency((a)))
|
||||
|
||||
// Duplicate stereo sources on the side/rear channels
|
||||
#define DEVICE_DUPLICATE_STEREO (1<<0)
|
||||
// Frequency was requested by the app or config file
|
||||
#define DEVICE_FREQUENCY_REQUEST (1<<1)
|
||||
// Channel configuration was requested by the config file
|
||||
@@ -616,9 +654,16 @@ struct ALCdevice_struct
|
||||
// Sample type was requested by the config file
|
||||
#define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
|
||||
|
||||
// Stereo sources cover 120-degree angles around +/-90
|
||||
#define DEVICE_WIDE_STEREO (1<<16)
|
||||
|
||||
// Specifies if the device is currently running
|
||||
#define DEVICE_RUNNING (1<<31)
|
||||
|
||||
/* Invalid channel offset */
|
||||
#define INVALID_OFFSET (~0u)
|
||||
|
||||
|
||||
#define LookupBuffer(m, k) ((struct ALbuffer*)LookupUIntMapKey(&(m)->BufferMap, (k)))
|
||||
#define LookupEffect(m, k) ((struct ALeffect*)LookupUIntMapKey(&(m)->EffectMap, (k)))
|
||||
#define LookupFilter(m, k) ((struct ALfilter*)LookupUIntMapKey(&(m)->FilterMap, (k)))
|
||||
@@ -631,7 +676,7 @@ struct ALCcontext_struct
|
||||
{
|
||||
volatile RefCount ref;
|
||||
|
||||
ALlistener Listener;
|
||||
struct ALlistener *Listener;
|
||||
|
||||
UIntMap SourceMap;
|
||||
UIntMap EffectSlotMap;
|
||||
@@ -645,7 +690,7 @@ struct ALCcontext_struct
|
||||
|
||||
volatile ALfloat DopplerFactor;
|
||||
volatile ALfloat DopplerVelocity;
|
||||
volatile ALfloat flSpeedOfSound;
|
||||
volatile ALfloat SpeedOfSound;
|
||||
volatile ALenum DeferUpdates;
|
||||
|
||||
struct ALsource **ActiveSources;
|
||||
@@ -667,25 +712,38 @@ struct ALCcontext_struct
|
||||
#define RemoveSource(m, k) ((struct ALsource*)RemoveUIntMapKey(&(m)->SourceMap, (k)))
|
||||
#define RemoveEffectSlot(m, k) ((struct ALeffectslot*)RemoveUIntMapKey(&(m)->EffectSlotMap, (k)))
|
||||
|
||||
|
||||
ALCcontext *GetContextRef(void);
|
||||
|
||||
void ALCcontext_IncRef(ALCcontext *context);
|
||||
void ALCcontext_DecRef(ALCcontext *context);
|
||||
|
||||
void AppendAllDeviceList(const ALCchar *name);
|
||||
void AppendAllDevicesList(const ALCchar *name);
|
||||
void AppendCaptureDeviceList(const ALCchar *name);
|
||||
|
||||
static __inline void LockDevice(ALCdevice *device)
|
||||
{ EnterCriticalSection(&device->Mutex); }
|
||||
static __inline void UnlockDevice(ALCdevice *device)
|
||||
{ LeaveCriticalSection(&device->Mutex); }
|
||||
void ALCdevice_LockDefault(ALCdevice *device);
|
||||
void ALCdevice_UnlockDefault(ALCdevice *device);
|
||||
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device);
|
||||
|
||||
static __inline void LockContext(ALCcontext *context)
|
||||
{ LockDevice(context->Device); }
|
||||
{ ALCdevice_Lock(context->Device); }
|
||||
static __inline void UnlockContext(ALCcontext *context)
|
||||
{ UnlockDevice(context->Device); }
|
||||
{ ALCdevice_Unlock(context->Device); }
|
||||
|
||||
|
||||
void *al_malloc(size_t alignment, size_t size);
|
||||
void *al_calloc(size_t alignment, size_t size);
|
||||
void al_free(void *ptr);
|
||||
|
||||
typedef struct {
|
||||
int state;
|
||||
#ifdef HAVE_SSE
|
||||
int sse_state;
|
||||
#endif
|
||||
} FPUCtl;
|
||||
void SetMixerFPUMode(FPUCtl *ctl);
|
||||
void RestoreFPUMode(const FPUCtl *ctl);
|
||||
|
||||
ALvoid *StartThread(ALuint (*func)(ALvoid*), ALvoid *ptr);
|
||||
ALuint StopThread(ALvoid *thread);
|
||||
|
||||
@@ -714,18 +772,21 @@ void SetDefaultWFXChannelOrder(ALCdevice *device);
|
||||
const ALCchar *DevFmtTypeString(enum DevFmtType type);
|
||||
const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans);
|
||||
|
||||
#define HRIR_BITS (5)
|
||||
#define HRIR_BITS (7)
|
||||
#define HRIR_LENGTH (1<<HRIR_BITS)
|
||||
#define HRIR_MASK (HRIR_LENGTH-1)
|
||||
void InitHrtf(void);
|
||||
void FreeHrtf(void);
|
||||
#define HRTFDELAY_BITS (20)
|
||||
#define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
|
||||
#define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
|
||||
const struct Hrtf *GetHrtf(ALCdevice *device);
|
||||
void FreeHrtfs(void);
|
||||
ALuint GetHrtfIrSize (const struct Hrtf *Hrtf);
|
||||
ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]);
|
||||
void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays);
|
||||
ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep);
|
||||
|
||||
void al_print(const char *func, const char *fmt, ...) PRINTF_STYLE(2,3);
|
||||
#define AL_PRINT(...) al_print(__FUNCTION__, __VA_ARGS__)
|
||||
void al_print(const char *type, const char *func, const char *fmt, ...) PRINTF_STYLE(3,4);
|
||||
#define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
|
||||
|
||||
extern FILE *LogFile;
|
||||
enum LogLevel {
|
||||
@@ -739,27 +800,83 @@ extern enum LogLevel LogLevel;
|
||||
|
||||
#define TRACEREF(...) do { \
|
||||
if(LogLevel >= LogRef) \
|
||||
AL_PRINT(__VA_ARGS__); \
|
||||
AL_PRINT("(--)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define TRACE(...) do { \
|
||||
if(LogLevel >= LogTrace) \
|
||||
AL_PRINT(__VA_ARGS__); \
|
||||
AL_PRINT("(II)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define WARN(...) do { \
|
||||
if(LogLevel >= LogWarning) \
|
||||
AL_PRINT(__VA_ARGS__); \
|
||||
AL_PRINT("(WW)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#define ERR(...) do { \
|
||||
if(LogLevel >= LogError) \
|
||||
AL_PRINT(__VA_ARGS__); \
|
||||
AL_PRINT("(EE)", __VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
|
||||
extern ALint RTPrioLevel;
|
||||
|
||||
|
||||
extern ALuint CPUCapFlags;
|
||||
enum {
|
||||
CPU_CAP_SSE = 1<<0,
|
||||
CPU_CAP_NEON = 1<<1,
|
||||
};
|
||||
|
||||
void FillCPUCaps(ALuint capfilter);
|
||||
|
||||
|
||||
/**
|
||||
* Starts a try block. Must not be nested within another try block within the
|
||||
* same function.
|
||||
*/
|
||||
#define al_try do { \
|
||||
int _al_err=0; \
|
||||
_al_try_label: \
|
||||
if(_al_err == 0)
|
||||
/**
|
||||
* After a try or another catch block, runs the next block if the given value
|
||||
* was thrown.
|
||||
*/
|
||||
#define al_catch(val) else if(_al_err == (val))
|
||||
/**
|
||||
* After a try or catch block, runs the next block for any value thrown and not
|
||||
* caught.
|
||||
*/
|
||||
#define al_catchany() else
|
||||
/** Marks the end of the final catch (or the try) block. */
|
||||
#define al_endtry } while(0)
|
||||
|
||||
/**
|
||||
* The given integer value is "thrown" so as to be caught by a catch block.
|
||||
* Must be called in a try block within the same function. The value must not
|
||||
* be 0.
|
||||
*/
|
||||
#define al_throw(e) do { \
|
||||
_al_err = (e); \
|
||||
assert(_al_err != 0); \
|
||||
goto _al_try_label; \
|
||||
} while(0)
|
||||
/** Sets an AL error on the given context, before throwing the error code. */
|
||||
#define al_throwerr(ctx, err) do { \
|
||||
alSetError((ctx), (err)); \
|
||||
al_throw((err)); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Throws an AL_INVALID_VALUE error with the given ctx if the given condition
|
||||
* is false.
|
||||
*/
|
||||
#define CHECK_VALUE(ctx, cond) do { \
|
||||
if(!(cond)) \
|
||||
al_throwerr((ctx), AL_INVALID_VALUE); \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+119
-71
@@ -3,9 +3,9 @@
|
||||
|
||||
#define MAX_SENDS 4
|
||||
|
||||
#include "alFilter.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "AL/al.h"
|
||||
#include "alFilter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -28,45 +28,77 @@ typedef struct ALbufferlistitem
|
||||
struct ALbufferlistitem *prev;
|
||||
} ALbufferlistitem;
|
||||
|
||||
typedef struct ALsource
|
||||
{
|
||||
volatile ALfloat flPitch;
|
||||
volatile ALfloat flGain;
|
||||
volatile ALfloat flOuterGain;
|
||||
volatile ALfloat flMinGain;
|
||||
volatile ALfloat flMaxGain;
|
||||
volatile ALfloat flInnerAngle;
|
||||
volatile ALfloat flOuterAngle;
|
||||
volatile ALfloat flRefDistance;
|
||||
volatile ALfloat flMaxDistance;
|
||||
volatile ALfloat flRollOffFactor;
|
||||
volatile ALfloat vPosition[3];
|
||||
volatile ALfloat vVelocity[3];
|
||||
volatile ALfloat vOrientation[3];
|
||||
volatile ALboolean bHeadRelative;
|
||||
volatile ALboolean bLooping;
|
||||
volatile enum DistanceModel DistanceModel;
|
||||
volatile ALboolean DirectChannels;
|
||||
typedef struct HrtfState {
|
||||
ALboolean Moving;
|
||||
ALuint Counter;
|
||||
ALIGN(16) ALfloat History[MaxChannels][SRC_HISTORY_LENGTH];
|
||||
ALIGN(16) ALfloat Values[MaxChannels][HRIR_LENGTH][2];
|
||||
ALuint Offset;
|
||||
} HrtfState;
|
||||
|
||||
enum Resampler Resampler;
|
||||
typedef struct HrtfParams {
|
||||
ALfloat Gain;
|
||||
ALfloat Dir[3];
|
||||
ALIGN(16) ALfloat Coeffs[MaxChannels][HRIR_LENGTH][2];
|
||||
ALIGN(16) ALfloat CoeffStep[HRIR_LENGTH][2];
|
||||
ALuint Delay[MaxChannels][2];
|
||||
ALint DelayStep[2];
|
||||
ALuint IrSize;
|
||||
} HrtfParams;
|
||||
|
||||
volatile ALenum state;
|
||||
ALenum new_state;
|
||||
ALuint position;
|
||||
ALuint position_fraction;
|
||||
|
||||
ALbufferlistitem *queue; // Linked list of buffers in queue
|
||||
ALuint BuffersInQueue; // Number of buffers in queue
|
||||
ALuint BuffersPlayed; // Number of buffers played on this loop
|
||||
|
||||
ALfloat DirectGain;
|
||||
ALfloat DirectGainHF;
|
||||
typedef struct DirectParams {
|
||||
ALfloat (*OutBuffer)[BUFFERSIZE];
|
||||
ALfloat *ClickRemoval;
|
||||
ALfloat *PendingClicks;
|
||||
|
||||
struct {
|
||||
struct ALeffectslot *Slot;
|
||||
ALfloat WetGain;
|
||||
ALfloat WetGainHF;
|
||||
} Send[MAX_SENDS];
|
||||
HrtfParams Params;
|
||||
HrtfState *State;
|
||||
} Hrtf;
|
||||
|
||||
/* 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. FrontLeft). Not used with HRTF. */
|
||||
ALfloat Gains[MaxChannels][MaxChannels];
|
||||
|
||||
/* A low-pass filter, using 2 chained one-pole filters. */
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MaxChannels*2];
|
||||
} DirectParams;
|
||||
|
||||
typedef struct SendParams {
|
||||
struct ALeffectslot *Slot;
|
||||
|
||||
/* Gain control, which applies to all input channels to a single (mono)
|
||||
* output buffer. */
|
||||
ALfloat Gain;
|
||||
|
||||
/* A low-pass filter, using 2 chained one-pole filters. */
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MaxChannels*2];
|
||||
} SendParams;
|
||||
|
||||
|
||||
typedef struct ALsource
|
||||
{
|
||||
/** Source properties. */
|
||||
volatile ALfloat Pitch;
|
||||
volatile ALfloat Gain;
|
||||
volatile ALfloat OuterGain;
|
||||
volatile ALfloat MinGain;
|
||||
volatile ALfloat MaxGain;
|
||||
volatile ALfloat InnerAngle;
|
||||
volatile ALfloat OuterAngle;
|
||||
volatile ALfloat RefDistance;
|
||||
volatile ALfloat MaxDistance;
|
||||
volatile ALfloat RollOffFactor;
|
||||
volatile ALfloat Position[3];
|
||||
volatile ALfloat Velocity[3];
|
||||
volatile ALfloat Orientation[3];
|
||||
volatile ALboolean HeadRelative;
|
||||
volatile ALboolean Looping;
|
||||
volatile enum DistanceModel DistanceModel;
|
||||
volatile ALboolean DirectChannels;
|
||||
|
||||
volatile ALboolean DryGainHFAuto;
|
||||
volatile ALboolean WetGainAuto;
|
||||
@@ -77,56 +109,72 @@ typedef struct ALsource
|
||||
volatile ALfloat RoomRolloffFactor;
|
||||
volatile ALfloat DopplerFactor;
|
||||
|
||||
ALint lOffset;
|
||||
ALint lOffsetType;
|
||||
enum Resampler Resampler;
|
||||
|
||||
// Source Type (Static, Streaming, or Undetermined)
|
||||
volatile ALint lSourceType;
|
||||
/**
|
||||
* Last user-specified offset, and the offset type (bytes, samples, or
|
||||
* seconds).
|
||||
*/
|
||||
ALdouble Offset;
|
||||
ALenum OffsetType;
|
||||
|
||||
/** Source type (static, streaming, or undetermined) */
|
||||
volatile ALint SourceType;
|
||||
|
||||
/** Source state (initial, playing, paused, or stopped) */
|
||||
volatile ALenum state;
|
||||
ALenum new_state;
|
||||
|
||||
/**
|
||||
* Source offset in samples, relative to the currently playing buffer, NOT
|
||||
* the whole queue, and the fractional (fixed-point) offset to the next
|
||||
* sample.
|
||||
*/
|
||||
ALuint position;
|
||||
ALuint position_fraction;
|
||||
|
||||
/** Source Buffer Queue info. */
|
||||
ALbufferlistitem *queue;
|
||||
ALuint BuffersInQueue;
|
||||
ALuint BuffersPlayed;
|
||||
|
||||
/** Current buffer sample info. */
|
||||
ALuint NumChannels;
|
||||
ALuint SampleSize;
|
||||
|
||||
/* HRTF info */
|
||||
ALboolean HrtfMoving;
|
||||
ALuint HrtfCounter;
|
||||
ALfloat HrtfHistory[MAXCHANNELS][SRC_HISTORY_LENGTH];
|
||||
ALfloat HrtfValues[MAXCHANNELS][HRIR_LENGTH][2];
|
||||
ALuint HrtfOffset;
|
||||
/** Direct filter and auxiliary send info. */
|
||||
ALfloat DirectGain;
|
||||
ALfloat DirectGainHF;
|
||||
|
||||
/* Current target parameters used for mixing */
|
||||
struct {
|
||||
MixerFunc DoMix;
|
||||
struct ALeffectslot *Slot;
|
||||
ALfloat Gain;
|
||||
ALfloat GainHF;
|
||||
} Send[MAX_SENDS];
|
||||
|
||||
/** HRTF info. */
|
||||
HrtfState Hrtf;
|
||||
|
||||
/** Current target parameters used for mixing. */
|
||||
struct {
|
||||
ResamplerFunc Resample;
|
||||
DryMixerFunc DryMix;
|
||||
WetMixerFunc WetMix;
|
||||
|
||||
ALint Step;
|
||||
|
||||
ALfloat HrtfGain;
|
||||
ALfloat HrtfDir[3];
|
||||
ALfloat HrtfCoeffs[MAXCHANNELS][HRIR_LENGTH][2];
|
||||
ALuint HrtfDelay[MAXCHANNELS][2];
|
||||
ALfloat HrtfCoeffStep[HRIR_LENGTH][2];
|
||||
ALint HrtfDelayStep[2];
|
||||
DirectParams Direct;
|
||||
|
||||
/* 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) */
|
||||
ALfloat DryGains[MAXCHANNELS][MAXCHANNELS];
|
||||
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MAXCHANNELS*2];
|
||||
|
||||
struct {
|
||||
struct ALeffectslot *Slot;
|
||||
ALfloat WetGain;
|
||||
FILTER iirFilter;
|
||||
ALfloat history[MAXCHANNELS];
|
||||
} Send[MAX_SENDS];
|
||||
SendParams Send[MAX_SENDS];
|
||||
} Params;
|
||||
/** Source needs to update its mixing parameters. */
|
||||
volatile ALenum NeedsUpdate;
|
||||
|
||||
/** Method to update mixing parameters. */
|
||||
ALvoid (*Update)(struct ALsource *self, const ALCcontext *context);
|
||||
|
||||
// Index to itself
|
||||
ALuint source;
|
||||
/** Self ID */
|
||||
ALuint id;
|
||||
} ALsource;
|
||||
#define ALsource_Update(s,a) ((s)->Update(s,a))
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#ifndef _AL_STATE_H_
|
||||
#define _AL_STATE_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+27
-213
@@ -1,40 +1,12 @@
|
||||
#ifndef _ALU_H_
|
||||
#define _ALU_H_
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "alMain.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#ifdef HAVE_FLOAT_H
|
||||
#include <float.h>
|
||||
/* HACK: Seems cross-compiling with MinGW includes the wrong float.h, which
|
||||
* doesn't define Windows' _controlfp and related macros */
|
||||
#if defined(__MINGW32__) && !defined(_RC_CHOP)
|
||||
/* Control word masks for unMask */
|
||||
#define _MCW_EM 0x0008001F /* Error masks */
|
||||
#define _MCW_IC 0x00040000 /* Infinity */
|
||||
#define _MCW_RC 0x00000300 /* Rounding */
|
||||
#define _MCW_PC 0x00030000 /* Precision */
|
||||
/* Control word values for unNew (use with related unMask above) */
|
||||
#define _EM_INVALID 0x00000010
|
||||
#define _EM_DENORMAL 0x00080000
|
||||
#define _EM_ZERODIVIDE 0x00000008
|
||||
#define _EM_OVERFLOW 0x00000004
|
||||
#define _EM_UNDERFLOW 0x00000002
|
||||
#define _EM_INEXACT 0x00000001
|
||||
#define _IC_AFFINE 0x00040000
|
||||
#define _IC_PROJECTIVE 0x00000000
|
||||
#define _RC_CHOP 0x00000300
|
||||
#define _RC_UP 0x00000200
|
||||
#define _RC_DOWN 0x00000100
|
||||
#define _RC_NEAR 0x00000000
|
||||
#define _PC_24 0x00020000
|
||||
#define _PC_53 0x00010000
|
||||
#define _PC_64 0x00000000
|
||||
_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _controlfp (unsigned int unNew, unsigned int unMask);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
@@ -44,74 +16,10 @@ _CRTIMP unsigned int __cdecl __MINGW_NOTHROW _controlfp (unsigned int unNew, uns
|
||||
#define F_PI (3.14159265358979323846f) /* pi */
|
||||
#define F_PI_2 (1.57079632679489661923f) /* pi/2 */
|
||||
|
||||
#ifdef HAVE_POWF
|
||||
#define aluPow(x,y) (powf((x),(y)))
|
||||
#else
|
||||
#define aluPow(x,y) ((ALfloat)pow((double)(x),(double)(y)))
|
||||
#ifndef FLT_EPSILON
|
||||
#define FLT_EPSILON (1.19209290e-07f)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SQRTF
|
||||
#define aluSqrt(x) (sqrtf((x)))
|
||||
#else
|
||||
#define aluSqrt(x) ((ALfloat)sqrt((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COSF
|
||||
#define aluCos(x) (cosf((x)))
|
||||
#else
|
||||
#define aluCos(x) ((ALfloat)cos((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SINF
|
||||
#define aluSin(x) (sinf((x)))
|
||||
#else
|
||||
#define aluSin(x) ((ALfloat)sin((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ACOSF
|
||||
#define aluAcos(x) (acosf((x)))
|
||||
#else
|
||||
#define aluAcos(x) ((ALfloat)acos((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ASINF
|
||||
#define aluAsin(x) (asinf((x)))
|
||||
#else
|
||||
#define aluAsin(x) ((ALfloat)asin((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATANF
|
||||
#define aluAtan(x) (atanf((x)))
|
||||
#else
|
||||
#define aluAtan(x) ((ALfloat)atan((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ATAN2F
|
||||
#define aluAtan2(x,y) (atan2f((x),(y)))
|
||||
#else
|
||||
#define aluAtan2(x,y) ((ALfloat)atan2((double)(x),(double)(y)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FABSF
|
||||
#define aluFabs(x) (fabsf((x)))
|
||||
#else
|
||||
#define aluFabs(x) ((ALfloat)fabs((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LOG10F
|
||||
#define aluLog10(x) (log10f((x)))
|
||||
#else
|
||||
#define aluLog10(x) ((ALfloat)log10((double)(x)))
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FLOORF
|
||||
#define aluFloor(x) (floorf((x)))
|
||||
#else
|
||||
#define aluFloor(x) ((ALfloat)floor((double)(x)))
|
||||
#endif
|
||||
|
||||
#define QUADRANT_NUM 128
|
||||
#define LUT_NUM (4 * QUADRANT_NUM)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -119,66 +27,29 @@ extern "C" {
|
||||
|
||||
struct ALsource;
|
||||
struct ALbuffer;
|
||||
struct DirectParams;
|
||||
struct SendParams;
|
||||
|
||||
typedef ALvoid (*MixerFunc)(struct ALsource *self, ALCdevice *Device,
|
||||
const ALvoid *RESTRICT data,
|
||||
ALuint *DataPosInt, ALuint *DataPosFrac,
|
||||
ALuint OutPos, ALuint SamplesToDo,
|
||||
ALuint BufferSize);
|
||||
typedef void (*ResamplerFunc)(const ALfloat *src, ALuint frac, ALuint increment,
|
||||
ALfloat *RESTRICT dst, ALuint dstlen);
|
||||
|
||||
enum Resampler {
|
||||
PointResampler,
|
||||
LinearResampler,
|
||||
CubicResampler,
|
||||
typedef ALvoid (*DryMixerFunc)(const struct DirectParams *params,
|
||||
const ALfloat *RESTRICT data, ALuint srcchan,
|
||||
ALuint OutPos, ALuint SamplesToDo,
|
||||
ALuint BufferSize);
|
||||
typedef ALvoid (*WetMixerFunc)(const struct SendParams *params,
|
||||
const ALfloat *RESTRICT data,
|
||||
ALuint OutPos, ALuint SamplesToDo,
|
||||
ALuint BufferSize);
|
||||
|
||||
ResamplerMax,
|
||||
};
|
||||
|
||||
enum Channel {
|
||||
FRONT_LEFT = 0,
|
||||
FRONT_RIGHT,
|
||||
FRONT_CENTER,
|
||||
LFE,
|
||||
BACK_LEFT,
|
||||
BACK_RIGHT,
|
||||
BACK_CENTER,
|
||||
SIDE_LEFT,
|
||||
SIDE_RIGHT,
|
||||
|
||||
MAXCHANNELS
|
||||
};
|
||||
|
||||
enum DistanceModel {
|
||||
InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
|
||||
LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
|
||||
ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
|
||||
InverseDistance = AL_INVERSE_DISTANCE,
|
||||
LinearDistance = AL_LINEAR_DISTANCE,
|
||||
ExponentDistance = AL_EXPONENT_DISTANCE,
|
||||
DisableDistance = AL_NONE,
|
||||
|
||||
DefaultDistanceModel = InverseDistanceClamped
|
||||
};
|
||||
|
||||
#define BUFFERSIZE 4096
|
||||
#define SPEEDOFSOUNDMETRESPERSEC (343.3f)
|
||||
#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
|
||||
|
||||
#define FRACTIONBITS (14)
|
||||
#define FRACTIONONE (1<<FRACTIONBITS)
|
||||
#define FRACTIONMASK (FRACTIONONE-1)
|
||||
|
||||
/* Size for temporary stack storage of buffer data. Must be a multiple of the
|
||||
* size of ALfloat, ie, 4. 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
|
||||
|
||||
|
||||
static __inline ALfloat minf(ALfloat a, ALfloat b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
@@ -208,6 +79,13 @@ static __inline ALint64 maxi64(ALint64 a, ALint64 b)
|
||||
static __inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max)
|
||||
{ return mini64(max, maxi64(min, val)); }
|
||||
|
||||
static __inline ALuint64 minu64(ALuint64 a, ALuint64 b)
|
||||
{ return ((a > b) ? b : a); }
|
||||
static __inline ALuint64 maxu64(ALuint64 a, ALuint64 b)
|
||||
{ return ((a > b) ? a : b); }
|
||||
static __inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max)
|
||||
{ return minu64(max, maxu64(min, val)); }
|
||||
|
||||
|
||||
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu)
|
||||
{
|
||||
@@ -225,81 +103,17 @@ static __inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat
|
||||
}
|
||||
|
||||
|
||||
static __inline int SetMixerFPUMode(void)
|
||||
{
|
||||
#if defined(_FPU_GETCW) && defined(_FPU_SETCW)
|
||||
fpu_control_t fpuState, newState;
|
||||
_FPU_GETCW(fpuState);
|
||||
newState = fpuState&~(_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE |
|
||||
_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO);
|
||||
newState |= _FPU_SINGLE | _FPU_RC_ZERO;
|
||||
_FPU_SETCW(newState);
|
||||
#else
|
||||
int fpuState;
|
||||
#if defined(HAVE__CONTROLFP)
|
||||
fpuState = _controlfp(0, 0);
|
||||
(void)_controlfp(_RC_CHOP|_PC_24, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
fpuState = fegetround();
|
||||
fesetround(FE_TOWARDZERO);
|
||||
#endif
|
||||
#endif
|
||||
return fpuState;
|
||||
}
|
||||
|
||||
static __inline void RestoreFPUMode(int state)
|
||||
{
|
||||
#if defined(_FPU_GETCW) && defined(_FPU_SETCW)
|
||||
fpu_control_t fpuState = state;
|
||||
_FPU_SETCW(fpuState);
|
||||
#elif defined(HAVE__CONTROLFP)
|
||||
_controlfp(state, _MCW_RC|_MCW_PC);
|
||||
#elif defined(HAVE_FESETROUND)
|
||||
fesetround(state);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static __inline void aluCrossproduct(const ALfloat *inVector1, const ALfloat *inVector2, ALfloat *outVector)
|
||||
{
|
||||
outVector[0] = inVector1[1]*inVector2[2] - inVector1[2]*inVector2[1];
|
||||
outVector[1] = inVector1[2]*inVector2[0] - inVector1[0]*inVector2[2];
|
||||
outVector[2] = inVector1[0]*inVector2[1] - inVector1[1]*inVector2[0];
|
||||
}
|
||||
|
||||
static __inline ALfloat aluDotproduct(const ALfloat *inVector1, const ALfloat *inVector2)
|
||||
{
|
||||
return inVector1[0]*inVector2[0] + inVector1[1]*inVector2[1] +
|
||||
inVector1[2]*inVector2[2];
|
||||
}
|
||||
|
||||
static __inline void aluNormalize(ALfloat *inVector)
|
||||
{
|
||||
ALfloat length, inverse_length;
|
||||
|
||||
length = aluSqrt(aluDotproduct(inVector, inVector));
|
||||
if(length > 0.0f)
|
||||
{
|
||||
inverse_length = 1.0f/length;
|
||||
inVector[0] *= inverse_length;
|
||||
inVector[1] *= inverse_length;
|
||||
inVector[2] *= inverse_length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ALvoid aluInitPanning(ALCdevice *Device);
|
||||
ALint aluCart2LUTpos(ALfloat re, ALfloat im);
|
||||
|
||||
ALvoid ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat *gains);
|
||||
|
||||
ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
|
||||
ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
|
||||
|
||||
MixerFunc SelectMixer(enum Resampler Resampler);
|
||||
MixerFunc SelectHrtfMixer(enum Resampler Resampler);
|
||||
|
||||
ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo);
|
||||
|
||||
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);
|
||||
/* Caller must lock the device. */
|
||||
ALvoid aluHandleDisconnect(ALCdevice *device);
|
||||
|
||||
extern ALfloat ConeScale;
|
||||
|
||||
+161
-182
@@ -32,67 +32,58 @@
|
||||
#include "alSource.h"
|
||||
|
||||
|
||||
static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count);
|
||||
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *val);
|
||||
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots);
|
||||
static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot);
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei cur = 0;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(n < 0 || IsBadWritePtr((void*)effectslots, n * sizeof(ALuint)))
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
ALenum err;
|
||||
ALsizei i;
|
||||
|
||||
err = ResizeEffectSlotArray(Context, n);
|
||||
if(err != AL_NO_ERROR)
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
alSetError(Context, err);
|
||||
n = 0;
|
||||
}
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
ALeffectslot *slot = calloc(1, sizeof(ALeffectslot));
|
||||
if(!slot || InitEffectSlot(slot) != AL_NO_ERROR)
|
||||
ALeffectslot *slot = al_calloc(16, sizeof(ALeffectslot));
|
||||
err = AL_OUT_OF_MEMORY;
|
||||
if(!slot || (err=InitEffectSlot(slot)) != AL_NO_ERROR)
|
||||
{
|
||||
free(slot);
|
||||
// We must have run out or memory
|
||||
alSetError(Context, AL_OUT_OF_MEMORY);
|
||||
alDeleteAuxiliaryEffectSlots(i, effectslots);
|
||||
al_free(slot);
|
||||
al_throwerr(Context, err);
|
||||
break;
|
||||
}
|
||||
|
||||
LockContext(Context);
|
||||
err = ResizeEffectSlotArray(Context, 1);
|
||||
err = NewThunkEntry(&slot->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot;
|
||||
UnlockContext(Context);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = NewThunkEntry(&slot->effectslot);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->effectslot, slot);
|
||||
err = InsertUIntMapEntry(&Context->EffectSlotMap, slot->id, slot);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
RemoveEffectSlotArray(Context, slot);
|
||||
FreeThunkEntry(slot->effectslot);
|
||||
FreeThunkEntry(slot->id);
|
||||
ALeffectState_Destroy(slot->EffectState);
|
||||
free(slot);
|
||||
al_free(slot);
|
||||
|
||||
alSetError(Context, err);
|
||||
alDeleteAuxiliaryEffectSlots(i, effectslots);
|
||||
break;
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
effectslots[i] = slot->effectslot;
|
||||
effectslots[cur] = slot->id;
|
||||
}
|
||||
err = AddEffectSlotArray(Context, n, effectslots);
|
||||
if(err != AL_NO_ERROR)
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
if(cur > 0)
|
||||
alDeleteAuxiliaryEffectSlots(cur, effectslots);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -100,48 +91,38 @@ AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslo
|
||||
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *EffectSlot;
|
||||
ALeffectslot *slot;
|
||||
ALsizei i;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(n < 0)
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
// Check that all effectslots are valid
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((EffectSlot=LookupEffectSlot(Context, effectslots[i])) == NULL)
|
||||
{
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
else if(EffectSlot->ref != 0)
|
||||
{
|
||||
alSetError(Context, AL_INVALID_OPERATION);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
if((slot=LookupEffectSlot(Context, effectslots[i])) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
if(slot->ref != 0)
|
||||
al_throwerr(Context, AL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
// All effectslots are valid
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
// Recheck that the effectslot is valid, because there could be duplicated names
|
||||
if((EffectSlot=RemoveEffectSlot(Context, effectslots[i])) == NULL)
|
||||
if((slot=RemoveEffectSlot(Context, effectslots[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(EffectSlot->effectslot);
|
||||
FreeThunkEntry(slot->id);
|
||||
|
||||
RemoveEffectSlotArray(Context, EffectSlot);
|
||||
ALeffectState_Destroy(EffectSlot->EffectState);
|
||||
RemoveEffectSlotArray(Context, slot);
|
||||
ALeffectState_Destroy(slot->EffectState);
|
||||
|
||||
memset(EffectSlot, 0, sizeof(ALeffectslot));
|
||||
free(EffectSlot);
|
||||
memset(slot, 0, sizeof(*slot));
|
||||
al_free(slot);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -161,59 +142,49 @@ AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot)
|
||||
return result;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue)
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint value)
|
||||
{
|
||||
ALCdevice *Device;
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *EffectSlot;
|
||||
ALeffectslot *Slot;
|
||||
ALeffect *effect = NULL;
|
||||
ALenum err;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL)
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT: {
|
||||
ALeffect *effect = NULL;
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
CHECK_VALUE(Context, value == 0 || (effect=LookupEffect(device, value)) != NULL);
|
||||
|
||||
if(iValue == 0 ||
|
||||
(effect=LookupEffect(Device, iValue)) != NULL)
|
||||
{
|
||||
ALenum err;
|
||||
err = InitializeEffect(Device, EffectSlot, effect);
|
||||
if(err != AL_NO_ERROR)
|
||||
alSetError(Context, err);
|
||||
else
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
} break;
|
||||
err = InitializeEffect(device, Slot, effect);
|
||||
if(err != AL_NO_ERROR)
|
||||
al_throwerr(Context, err);
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
if(iValue == AL_TRUE || iValue == AL_FALSE)
|
||||
{
|
||||
EffectSlot->AuxSendAuto = iValue;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
CHECK_VALUE(Context, value == AL_TRUE || value == AL_FALSE);
|
||||
|
||||
Slot->AuxSendAuto = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues)
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
@@ -221,122 +192,119 @@ AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum para
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
alAuxiliaryEffectSloti(effectslot, param, piValues[0]);
|
||||
alAuxiliaryEffectSloti(effectslot, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(LookupEffectSlot(Context, effectslot) != NULL)
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue)
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *EffectSlot;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL)
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
if(flValue >= 0.0f && flValue <= 1.0f)
|
||||
{
|
||||
EffectSlot->Gain = flValue;
|
||||
EffectSlot->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
CHECK_VALUE(Context, value >= 0.0f && value <= 1.0f);
|
||||
|
||||
Slot->Gain = value;
|
||||
Slot->NeedsUpdate = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues)
|
||||
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
alAuxiliaryEffectSlotf(effectslot, param, pflValues[0]);
|
||||
alAuxiliaryEffectSlotf(effectslot, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(LookupEffectSlot(Context, effectslot) != NULL)
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *EffectSlot;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL)
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
*piValue = EffectSlot->effect.effect;
|
||||
*value = Slot->effect.id;
|
||||
break;
|
||||
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
*piValue = EffectSlot->AuxSendAuto;
|
||||
*value = Slot->AuxSendAuto;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues)
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
@@ -344,80 +312,80 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum p
|
||||
{
|
||||
case AL_EFFECTSLOT_EFFECT:
|
||||
case AL_EFFECTSLOT_AUXILIARY_SEND_AUTO:
|
||||
alGetAuxiliaryEffectSloti(effectslot, param, piValues);
|
||||
alGetAuxiliaryEffectSloti(effectslot, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(LookupEffectSlot(Context, effectslot) != NULL)
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALeffectslot *EffectSlot;
|
||||
ALeffectslot *Slot;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if((EffectSlot=LookupEffectSlot(Context, effectslot)) != NULL)
|
||||
al_try
|
||||
{
|
||||
if((Slot=LookupEffectSlot(Context, effectslot)) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
*pflValue = EffectSlot->Gain;
|
||||
*value = Slot->Gain;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues)
|
||||
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECTSLOT_GAIN:
|
||||
alGetAuxiliaryEffectSlotf(effectslot, param, pflValues);
|
||||
alGetAuxiliaryEffectSlotf(effectslot, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(LookupEffectSlot(Context, effectslot) != NULL)
|
||||
al_try
|
||||
{
|
||||
if(LookupEffectSlot(Context, effectslot) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -437,7 +405,7 @@ static ALvoid NoneUpdate(ALeffectState *State, ALCdevice *Device, const ALeffect
|
||||
(void)Device;
|
||||
(void)Slot;
|
||||
}
|
||||
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[MAXCHANNELS])
|
||||
static ALvoid NoneProcess(ALeffectState *State, ALuint SamplesToDo, const ALfloat *RESTRICT SamplesIn, ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE])
|
||||
{
|
||||
(void)State;
|
||||
(void)SamplesToDo;
|
||||
@@ -481,23 +449,35 @@ static ALvoid RemoveEffectSlotArray(ALCcontext *Context, ALeffectslot *slot)
|
||||
UnlockContext(Context);
|
||||
}
|
||||
|
||||
static ALenum ResizeEffectSlotArray(ALCcontext *Context, ALsizei count)
|
||||
static ALenum AddEffectSlotArray(ALCcontext *Context, ALsizei count, const ALuint *slots)
|
||||
{
|
||||
ALsizei newcount;
|
||||
void *temp;
|
||||
ALsizei i;
|
||||
|
||||
if(count <= Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount)
|
||||
return AL_NO_ERROR;
|
||||
LockContext(Context);
|
||||
if(count > Context->MaxActiveEffectSlots-Context->ActiveEffectSlotCount)
|
||||
{
|
||||
ALsizei newcount;
|
||||
void *temp = NULL;
|
||||
|
||||
newcount = Context->MaxActiveEffectSlots ?
|
||||
(Context->MaxActiveEffectSlots<<1) : 1;
|
||||
if(newcount <= Context->MaxActiveEffectSlots ||
|
||||
!(temp=realloc(Context->ActiveEffectSlots, newcount *
|
||||
sizeof(*Context->ActiveEffectSlots))))
|
||||
return AL_OUT_OF_MEMORY;
|
||||
|
||||
Context->ActiveEffectSlots = temp;
|
||||
Context->MaxActiveEffectSlots = newcount;
|
||||
newcount = Context->MaxActiveEffectSlots ? (Context->MaxActiveEffectSlots<<1) : 1;
|
||||
if(newcount > Context->MaxActiveEffectSlots)
|
||||
temp = realloc(Context->ActiveEffectSlots,
|
||||
newcount * sizeof(*Context->ActiveEffectSlots));
|
||||
if(!temp)
|
||||
{
|
||||
UnlockContext(Context);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
Context->ActiveEffectSlots = temp;
|
||||
Context->MaxActiveEffectSlots = newcount;
|
||||
}
|
||||
for(i = 0;i < count;i++)
|
||||
{
|
||||
ALeffectslot *slot = LookupEffectSlot(Context, slots[i]);
|
||||
assert(slot != NULL);
|
||||
Context->ActiveEffectSlots[Context->ActiveEffectSlotCount++] = slot;
|
||||
}
|
||||
UnlockContext(Context);
|
||||
return AL_NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -507,7 +487,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
ALeffectState *State = NULL;
|
||||
ALenum err = AL_NO_ERROR;
|
||||
|
||||
LockDevice(Device);
|
||||
ALCdevice_Lock(Device);
|
||||
if(newtype == AL_EFFECT_NULL && EffectSlot->effect.type != AL_EFFECT_NULL)
|
||||
{
|
||||
State = NoneCreate();
|
||||
@@ -542,19 +522,19 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
return err;
|
||||
}
|
||||
|
||||
if(State)
|
||||
{
|
||||
int oldMode;
|
||||
oldMode = SetMixerFPUMode();
|
||||
FPUCtl oldMode;
|
||||
SetMixerFPUMode(&oldMode);
|
||||
|
||||
if(ALeffectState_DeviceUpdate(State, Device) == AL_FALSE)
|
||||
{
|
||||
RestoreFPUMode(oldMode);
|
||||
UnlockDevice(Device);
|
||||
RestoreFPUMode(&oldMode);
|
||||
ALCdevice_Unlock(Device);
|
||||
ALeffectState_Destroy(State);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -569,9 +549,9 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
* be called. */
|
||||
EffectSlot->NeedsUpdate = AL_FALSE;
|
||||
ALeffectState_Update(EffectSlot->EffectState, Device, EffectSlot);
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
|
||||
RestoreFPUMode(oldMode);
|
||||
RestoreFPUMode(&oldMode);
|
||||
|
||||
ALeffectState_Destroy(State);
|
||||
State = NULL;
|
||||
@@ -582,7 +562,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
memset(&EffectSlot->effect, 0, sizeof(EffectSlot->effect));
|
||||
else
|
||||
memcpy(&EffectSlot->effect, effect, sizeof(*effect));
|
||||
UnlockDevice(Device);
|
||||
ALCdevice_Unlock(Device);
|
||||
EffectSlot->NeedsUpdate = AL_TRUE;
|
||||
}
|
||||
|
||||
@@ -592,7 +572,7 @@ ALenum InitializeEffect(ALCdevice *Device, ALeffectslot *EffectSlot, ALeffect *e
|
||||
|
||||
ALenum InitEffectSlot(ALeffectslot *slot)
|
||||
{
|
||||
ALint i;
|
||||
ALint i, c;
|
||||
|
||||
if(!(slot->EffectState=NoneCreate()))
|
||||
return AL_OUT_OF_MEMORY;
|
||||
@@ -600,12 +580,12 @@ ALenum InitEffectSlot(ALeffectslot *slot)
|
||||
slot->Gain = 1.0;
|
||||
slot->AuxSendAuto = AL_TRUE;
|
||||
slot->NeedsUpdate = AL_FALSE;
|
||||
for(i = 0;i < BUFFERSIZE;i++)
|
||||
slot->WetBuffer[i] = 0.0f;
|
||||
for(i = 0;i < 1;i++)
|
||||
for(c = 0;c < 1;c++)
|
||||
{
|
||||
slot->ClickRemoval[i] = 0.0f;
|
||||
slot->PendingClicks[i] = 0.0f;
|
||||
for(i = 0;i < BUFFERSIZE;i++)
|
||||
slot->WetBuffer[c][i] = 0.0f;
|
||||
slot->ClickRemoval[c] = 0.0f;
|
||||
slot->PendingClicks[c] = 0.0f;
|
||||
}
|
||||
slot->ref = 0;
|
||||
|
||||
@@ -620,11 +600,10 @@ ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context)
|
||||
ALeffectslot *temp = Context->EffectSlotMap.array[pos].value;
|
||||
Context->EffectSlotMap.array[pos].value = NULL;
|
||||
|
||||
// Release effectslot structure
|
||||
ALeffectState_Destroy(temp->EffectState);
|
||||
|
||||
FreeThunkEntry(temp->effectslot);
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALeffectslot));
|
||||
free(temp);
|
||||
al_free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
+425
-468
File diff suppressed because it is too large
Load Diff
+105
-100
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
@@ -40,46 +41,48 @@ static void InitEffectParams(ALeffect *effect, ALenum type);
|
||||
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei i;
|
||||
ALsizei cur = 0;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(n < 0 || IsBadWritePtr((void*)effects, n * sizeof(ALuint)))
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
ALenum err;
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALeffect *effect = calloc(1, sizeof(ALeffect));
|
||||
if(!effect || InitEffect(effect) != AL_NO_ERROR)
|
||||
err = AL_OUT_OF_MEMORY;
|
||||
if(!effect || (err=InitEffect(effect)) != AL_NO_ERROR)
|
||||
{
|
||||
free(effect);
|
||||
alSetError(Context, AL_OUT_OF_MEMORY);
|
||||
alDeleteEffects(i, effects);
|
||||
break;
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
err = NewThunkEntry(&effect->effect);
|
||||
err = NewThunkEntry(&effect->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->EffectMap, effect->effect, effect);
|
||||
err = InsertUIntMapEntry(&device->EffectMap, effect->id, effect);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(effect->effect);
|
||||
FreeThunkEntry(effect->id);
|
||||
memset(effect, 0, sizeof(ALeffect));
|
||||
free(effect);
|
||||
|
||||
alSetError(Context, err);
|
||||
alDeleteEffects(i, effects);
|
||||
break;
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
effects[i] = effect->effect;
|
||||
effects[cur] = effect->id;
|
||||
}
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
if(cur > 0)
|
||||
alDeleteEffects(cur, effects);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -87,43 +90,33 @@ AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
|
||||
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *device;
|
||||
ALeffect *ALEffect;
|
||||
ALeffect *Effect;
|
||||
ALsizei i;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
device = Context->Device;
|
||||
if(n < 0)
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
// Check that all effects are valid
|
||||
ALCdevice *device = Context->Device;
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if(!effects[i])
|
||||
continue;
|
||||
|
||||
if(LookupEffect(device, effects[i]) == NULL)
|
||||
{
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
if(effects[i] && LookupEffect(device, effects[i]) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
}
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
// Recheck that the effect is valid, because there could be duplicated names
|
||||
if((ALEffect=RemoveEffect(device, effects[i])) == NULL)
|
||||
if((Effect=RemoveEffect(device, effects[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(ALEffect->effect);
|
||||
FreeThunkEntry(Effect->id);
|
||||
|
||||
memset(ALEffect, 0, sizeof(ALeffect));
|
||||
free(ALEffect);
|
||||
memset(Effect, 0, sizeof(*Effect));
|
||||
free(Effect);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -144,7 +137,7 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
|
||||
return result;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
|
||||
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -154,58 +147,65 @@ AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue)
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
if(param == AL_EFFECT_TYPE)
|
||||
{
|
||||
ALboolean isOk = (iValue == AL_EFFECT_NULL);
|
||||
ALboolean isOk = (value == AL_EFFECT_NULL);
|
||||
ALint i;
|
||||
for(i = 0;!isOk && EffectList[i].val;i++)
|
||||
{
|
||||
if(iValue == EffectList[i].val &&
|
||||
if(value == EffectList[i].val &&
|
||||
!DisabledEffects[EffectList[i].type])
|
||||
isOk = AL_TRUE;
|
||||
}
|
||||
|
||||
if(isOk)
|
||||
InitEffectParams(ALEffect, iValue);
|
||||
InitEffectParams(ALEffect, value);
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_SetParami(ALEffect, Context, param, iValue);
|
||||
ALeffect_SetParami(ALEffect, Context, param, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues)
|
||||
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALeffect *ALEffect;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECT_TYPE:
|
||||
alEffecti(effect, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_SetParamiv(ALEffect, Context, param, piValues);
|
||||
ALeffect_SetParamiv(ALEffect, Context, param, values);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue)
|
||||
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -215,18 +215,18 @@ AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_SetParamf(ALEffect, Context, param, flValue);
|
||||
ALeffect_SetParamf(ALEffect, Context, param, value);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues)
|
||||
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -236,18 +236,18 @@ AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_SetParamfv(ALEffect, Context, param, pflValues);
|
||||
ALeffect_SetParamfv(ALEffect, Context, param, values);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -257,25 +257,51 @@ AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piVal
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
if(param == AL_EFFECT_TYPE)
|
||||
{
|
||||
*piValue = ALEffect->type;
|
||||
}
|
||||
*value = ALEffect->type;
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_GetParamiv(ALEffect, Context, param, piValue);
|
||||
ALeffect_GetParami(ALEffect, Context, param, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues)
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALeffect *ALEffect;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_EFFECT_TYPE:
|
||||
alGetEffecti(effect, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_GetParamiv(ALEffect, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -285,18 +311,18 @@ AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piVa
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_GetParamiv(ALEffect, Context, param, piValues);
|
||||
ALeffect_GetParamf(ALEffect, Context, param, value);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -306,34 +332,13 @@ AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pfl
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
if((ALEffect=LookupEffect(Device, effect)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_GetParamf(ALEffect, Context, param, pflValue);
|
||||
ALeffect_GetParamfv(ALEffect, Context, param, values);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALeffect *ALEffect;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALEffect=LookupEffect(Device, effect)) != NULL)
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALeffect_GetParamfv(ALEffect, Context, param, pflValues);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -1188,7 +1193,7 @@ ALvoid ReleaseALEffects(ALCdevice *device)
|
||||
device->EffectMap.array[i].value = NULL;
|
||||
|
||||
// Release effect structure
|
||||
FreeThunkEntry(temp->effect);
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALeffect));
|
||||
free(temp);
|
||||
}
|
||||
|
||||
+27
-15
@@ -28,21 +28,6 @@
|
||||
|
||||
ALboolean TrapALError = AL_FALSE;
|
||||
|
||||
AL_API ALenum AL_APIENTRY alGetError(void)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_INVALID_OPERATION;
|
||||
|
||||
errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
|
||||
{
|
||||
if(TrapALError)
|
||||
@@ -57,3 +42,30 @@ ALvoid alSetError(ALCcontext *Context, ALenum errorCode)
|
||||
}
|
||||
CompExchangeInt(&Context->LastError, AL_NO_ERROR, errorCode);
|
||||
}
|
||||
|
||||
AL_API ALenum AL_APIENTRY alGetError(void)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALenum errorCode;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context)
|
||||
{
|
||||
if(TrapALError)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(IsDebuggerPresent())
|
||||
DebugBreak();
|
||||
#elif defined(SIGTRAP)
|
||||
raise(SIGTRAP);
|
||||
#endif
|
||||
}
|
||||
return AL_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
errorCode = ExchangeInt(&Context->LastError, AL_NO_ERROR);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
+10
-312
@@ -34,297 +34,6 @@
|
||||
#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 },
|
||||
{ "AL_DIRECT_CHANNELS_SOFT", AL_DIRECT_CHANNELS_SOFT },
|
||||
|
||||
// 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_EXT },
|
||||
{ "AL_FORMAT_STEREO_MULAW", AL_FORMAT_STEREO_MULAW },
|
||||
{ "AL_FORMAT_STEREO_MULAW_EXT", AL_FORMAT_STEREO_MULAW_EXT },
|
||||
{ "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 },
|
||||
{ "AL_FORMAT_MONO_ALAW_EXT", AL_FORMAT_MONO_ALAW_EXT },
|
||||
{ "AL_FORMAT_STEREO_ALAW_EXT", AL_FORMAT_STEREO_ALAW_EXT },
|
||||
|
||||
// Internal Buffer Formats
|
||||
{ "AL_MONO8_SOFT", AL_MONO8_SOFT },
|
||||
{ "AL_MONO16_SOFT", AL_MONO16_SOFT },
|
||||
{ "AL_MONO32F_SOFT", AL_MONO32F_SOFT },
|
||||
{ "AL_STEREO8_SOFT", AL_STEREO8_SOFT },
|
||||
{ "AL_STEREO16_SOFT", AL_STEREO16_SOFT },
|
||||
{ "AL_STEREO32F_SOFT", AL_STEREO32F_SOFT },
|
||||
{ "AL_QUAD8_SOFT", AL_QUAD8_SOFT },
|
||||
{ "AL_QUAD16_SOFT", AL_QUAD16_SOFT },
|
||||
{ "AL_QUAD32F_SOFT", AL_QUAD32F_SOFT },
|
||||
{ "AL_REAR8_SOFT", AL_REAR8_SOFT },
|
||||
{ "AL_REAR16_SOFT", AL_REAR16_SOFT },
|
||||
{ "AL_REAR32F_SOFT", AL_REAR32F_SOFT },
|
||||
{ "AL_5POINT1_8_SOFT", AL_5POINT1_8_SOFT },
|
||||
{ "AL_5POINT1_16_SOFT", AL_5POINT1_16_SOFT },
|
||||
{ "AL_5POINT1_32F_SOFT", AL_5POINT1_32F_SOFT },
|
||||
{ "AL_6POINT1_8_SOFT", AL_6POINT1_8_SOFT },
|
||||
{ "AL_6POINT1_16_SOFT", AL_6POINT1_16_SOFT },
|
||||
{ "AL_6POINT1_32F_SOFT", AL_6POINT1_32F_SOFT },
|
||||
{ "AL_7POINT1_8_SOFT", AL_7POINT1_8_SOFT },
|
||||
{ "AL_7POINT1_16_SOFT", AL_7POINT1_16_SOFT },
|
||||
{ "AL_7POINT1_32F_SOFT", AL_7POINT1_32F_SOFT },
|
||||
|
||||
// Buffer Channel Configurations
|
||||
{ "AL_MONO_SOFT", AL_MONO_SOFT },
|
||||
{ "AL_STEREO_SOFT", AL_STEREO_SOFT },
|
||||
{ "AL_QUAD_SOFT", AL_QUAD_SOFT },
|
||||
{ "AL_REAR_SOFT", AL_REAR_SOFT },
|
||||
{ "AL_5POINT1_SOFT", AL_5POINT1_SOFT },
|
||||
{ "AL_6POINT1_SOFT", AL_6POINT1_SOFT },
|
||||
{ "AL_7POINT1_SOFT", AL_7POINT1_SOFT },
|
||||
|
||||
// Buffer Sample Types
|
||||
{ "AL_BYTE_SOFT", AL_BYTE_SOFT },
|
||||
{ "AL_UNSIGNED_BYTE_SOFT", AL_UNSIGNED_BYTE_SOFT },
|
||||
{ "AL_SHORT_SOFT", AL_SHORT_SOFT },
|
||||
{ "AL_UNSIGNED_SHORT_SOFT", AL_UNSIGNED_SHORT_SOFT },
|
||||
{ "AL_INT_SOFT", AL_INT_SOFT },
|
||||
{ "AL_UNSIGNED_INT_SOFT", AL_UNSIGNED_INT_SOFT },
|
||||
{ "AL_FLOAT_SOFT", AL_FLOAT_SOFT },
|
||||
{ "AL_DOUBLE_SOFT", AL_DOUBLE_SOFT },
|
||||
{ "AL_BYTE3_SOFT", AL_BYTE3_SOFT },
|
||||
{ "AL_UNSIGNED_BYTE3_SOFT", AL_UNSIGNED_BYTE3_SOFT },
|
||||
|
||||
// Buffer attributes
|
||||
{ "AL_FREQUENCY", AL_FREQUENCY },
|
||||
{ "AL_BITS", AL_BITS },
|
||||
{ "AL_CHANNELS", AL_CHANNELS },
|
||||
{ "AL_SIZE", AL_SIZE },
|
||||
{ "AL_INTERNAL_FORMAT_SOFT", AL_INTERNAL_FORMAT_SOFT },
|
||||
{ "AL_BYTE_LENGTH_SOFT", AL_BYTE_LENGTH_SOFT },
|
||||
{ "AL_SAMPLE_LENGTH_SOFT", AL_SAMPLE_LENGTH_SOFT },
|
||||
{ "AL_SEC_LENGTH_SOFT", AL_SEC_LENGTH_SOFT },
|
||||
|
||||
// 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 },
|
||||
{ "AL_DEFERRED_UPDATES_SOFT", AL_DEFERRED_UPDATES_SOFT },
|
||||
|
||||
// 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
|
||||
{ "AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT",AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT},
|
||||
{ "AL_EFFECT_DEDICATED_DIALOGUE", AL_EFFECT_DEDICATED_DIALOGUE },
|
||||
|
||||
// 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 },
|
||||
|
||||
// Dedicated Dialogue/LFE params
|
||||
{ "AL_DEDICATED_GAIN", AL_DEDICATED_GAIN },
|
||||
|
||||
|
||||
// Default
|
||||
{ NULL, (ALenum)0 }
|
||||
};
|
||||
|
||||
|
||||
const struct EffectList EffectList[] = {
|
||||
{ "eaxreverb", EAXREVERB, "AL_EFFECT_EAXREVERB", AL_EFFECT_EAXREVERB },
|
||||
@@ -339,7 +48,7 @@ const struct EffectList EffectList[] = {
|
||||
|
||||
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
{
|
||||
ALboolean bIsSupported = AL_FALSE;
|
||||
ALboolean ret = AL_FALSE;
|
||||
ALCcontext *Context;
|
||||
const char *ptr;
|
||||
size_t len;
|
||||
@@ -347,10 +56,10 @@ AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
if(!extName)
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, extName);
|
||||
|
||||
len = strlen(extName);
|
||||
ptr = Context->ExtensionList;
|
||||
while(ptr && *ptr)
|
||||
@@ -358,7 +67,7 @@ AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
if(strncasecmp(ptr, extName, len) == 0 &&
|
||||
(ptr[len] == '\0' || isspace(ptr[len])))
|
||||
{
|
||||
bIsSupported = AL_TRUE;
|
||||
ret = AL_TRUE;
|
||||
break;
|
||||
}
|
||||
if((ptr=strchr(ptr, ' ')) != NULL)
|
||||
@@ -369,9 +78,10 @@ AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName)
|
||||
}
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
return bIsSupported;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -384,19 +94,7 @@ AL_API ALvoid* AL_APIENTRY alGetProcAddress(const ALchar *funcName)
|
||||
|
||||
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *enumName)
|
||||
{
|
||||
ALsizei i;
|
||||
|
||||
for(i = 0;EffectList[i].ename;i++)
|
||||
{
|
||||
if(DisabledEffects[EffectList[i].type] &&
|
||||
strcmp(EffectList[i].ename, enumName) == 0)
|
||||
return (ALenum)0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(enumeration[i].enumName &&
|
||||
strcmp(enumeration[i].enumName, enumName) != 0)
|
||||
i++;
|
||||
|
||||
return enumeration[i].value;
|
||||
if(!enumName)
|
||||
return (ALenum)0;
|
||||
return alcGetEnumValue(NULL, enumName);
|
||||
}
|
||||
|
||||
+152
-170
@@ -22,9 +22,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "alMain.h"
|
||||
#include "alu.h"
|
||||
#include "alFilter.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
@@ -36,46 +35,45 @@ static void InitFilterParams(ALfilter *filter, ALenum type);
|
||||
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALsizei i;
|
||||
ALsizei cur = 0;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(n < 0 || IsBadWritePtr((void*)filters, n * sizeof(ALuint)))
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
ALCdevice *device = Context->Device;
|
||||
ALenum err;
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALfilter *filter = calloc(1, sizeof(ALfilter));
|
||||
if(!filter)
|
||||
{
|
||||
alSetError(Context, AL_OUT_OF_MEMORY);
|
||||
alDeleteFilters(i, filters);
|
||||
break;
|
||||
}
|
||||
al_throwerr(Context, AL_OUT_OF_MEMORY);
|
||||
InitFilterParams(filter, AL_FILTER_NULL);
|
||||
|
||||
err = NewThunkEntry(&filter->filter);
|
||||
err = NewThunkEntry(&filter->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->FilterMap, filter->filter, filter);
|
||||
err = InsertUIntMapEntry(&device->FilterMap, filter->id, filter);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(filter->filter);
|
||||
FreeThunkEntry(filter->id);
|
||||
memset(filter, 0, sizeof(ALfilter));
|
||||
free(filter);
|
||||
|
||||
alSetError(Context, err);
|
||||
alDeleteFilters(i, filters);
|
||||
break;
|
||||
al_throwerr(Context, err);
|
||||
}
|
||||
|
||||
filters[i] = filter->filter;
|
||||
filters[cur] = filter->id;
|
||||
}
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
if(cur > 0)
|
||||
alDeleteFilters(cur, filters);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -83,43 +81,33 @@ AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters)
|
||||
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *device;
|
||||
ALfilter *ALFilter;
|
||||
ALfilter *Filter;
|
||||
ALsizei i;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
device = Context->Device;
|
||||
if(n < 0)
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
else
|
||||
al_try
|
||||
{
|
||||
// Check that all filters are valid
|
||||
ALCdevice *device = Context->Device;
|
||||
CHECK_VALUE(Context, n >= 0);
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if(!filters[i])
|
||||
continue;
|
||||
|
||||
if(LookupFilter(device, filters[i]) == NULL)
|
||||
{
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
n = 0;
|
||||
break;
|
||||
}
|
||||
if(filters[i] && LookupFilter(device, filters[i]) == NULL)
|
||||
al_throwerr(Context, AL_INVALID_NAME);
|
||||
}
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
// Recheck that the filter is valid, because there could be duplicated names
|
||||
if((ALFilter=RemoveFilter(device, filters[i])) == NULL)
|
||||
if((Filter=RemoveFilter(device, filters[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(ALFilter->filter);
|
||||
FreeThunkEntry(Filter->id);
|
||||
|
||||
memset(ALFilter, 0, sizeof(ALfilter));
|
||||
free(ALFilter);
|
||||
memset(Filter, 0, sizeof(*Filter));
|
||||
free(Filter);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -140,7 +128,7 @@ AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter)
|
||||
return result;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
|
||||
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -150,130 +138,28 @@ AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue)
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
switch(param)
|
||||
if(param == AL_FILTER_TYPE)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
if(iValue == AL_FILTER_NULL || iValue == AL_FILTER_LOWPASS)
|
||||
InitFilterParams(ALFilter, iValue);
|
||||
if(value == AL_FILTER_NULL || value == AL_FILTER_LOWPASS)
|
||||
InitFilterParams(ALFilter, value);
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParami(ALFilter, Context, param, iValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
alFilteri(filter, param, piValues[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamiv(ALFilter, Context, param, piValues);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamf(ALFilter, Context, param, flValue);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_SetParamfv(ALFilter, Context, param, pflValues);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
{
|
||||
switch(param)
|
||||
else
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
*piValue = ALFilter->type;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParami(ALFilter, Context, param, piValue);
|
||||
break;
|
||||
ALfilter_SetParami(ALFilter, Context, param, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues)
|
||||
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -282,7 +168,7 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piVa
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
alGetFilteri(filter, param, piValues);
|
||||
alFilteri(filter, param, values[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -290,18 +176,18 @@ AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piVa
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamiv(ALFilter, Context, param, piValues);
|
||||
ALfilter_SetParamiv(ALFilter, Context, param, values);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue)
|
||||
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -311,18 +197,18 @@ AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pfl
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamf(ALFilter, Context, param, pflValue);
|
||||
ALfilter_SetParamf(ALFilter, Context, param, value);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues)
|
||||
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
@@ -332,13 +218,109 @@ AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pf
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) != NULL)
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamfv(ALFilter, Context, param, pflValues);
|
||||
ALfilter_SetParamfv(ALFilter, Context, param, values);
|
||||
}
|
||||
else
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
if(param == AL_FILTER_TYPE)
|
||||
*value = ALFilter->type;
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParami(ALFilter, Context, param, value);
|
||||
}
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_FILTER_TYPE:
|
||||
alGetFilteri(filter, param, values);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamiv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamf(ALFilter, Context, param, value);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALCdevice *Device;
|
||||
ALfilter *ALFilter;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
Device = Context->Device;
|
||||
if((ALFilter=LookupFilter(Device, filter)) == NULL)
|
||||
alSetError(Context, AL_INVALID_NAME);
|
||||
else
|
||||
{
|
||||
/* Call the appropriate handler */
|
||||
ALfilter_GetParamfv(ALFilter, Context, param, values);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -348,12 +330,12 @@ ALfloat lpCoeffCalc(ALfloat g, ALfloat cw)
|
||||
{
|
||||
ALfloat a = 0.0f;
|
||||
|
||||
/* Be careful with gains < 0.001, as that causes the coefficient head
|
||||
* towards 1, which will flatten the signal */
|
||||
if(g < 0.9999f) /* 1-epsilon */
|
||||
{
|
||||
/* Be careful with gains < 0.001, as that causes the coefficient head
|
||||
* towards 1, which will flatten the signal */
|
||||
g = maxf(g, 0.001f);
|
||||
a = (1 - g*cw - aluSqrt(2*g*(1-cw) - g*g*(1 - cw*cw))) /
|
||||
a = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) /
|
||||
(1 - g);
|
||||
}
|
||||
|
||||
@@ -448,7 +430,7 @@ ALvoid ReleaseALFilters(ALCdevice *device)
|
||||
device->FilterMap.array[i].value = NULL;
|
||||
|
||||
// Release filter structure
|
||||
FreeThunkEntry(temp->filter);
|
||||
FreeThunkEntry(temp->id);
|
||||
memset(temp, 0, sizeof(ALfilter));
|
||||
free(temp);
|
||||
}
|
||||
|
||||
+295
-336
@@ -26,488 +26,447 @@
|
||||
#include "alListener.h"
|
||||
#include "alSource.h"
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListenerf(ALenum eParam, ALfloat flValue)
|
||||
AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(eParam)
|
||||
al_try
|
||||
{
|
||||
case AL_GAIN:
|
||||
if(flValue >= 0.0f && isfinite(flValue))
|
||||
{
|
||||
Context->Listener.Gain = flValue;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
if(flValue > 0.0f && isfinite(flValue))
|
||||
{
|
||||
Context->Listener.MetersPerUnit = flValue;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListener3f(ALenum eParam, ALfloat flValue1, ALfloat flValue2, ALfloat flValue3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
|
||||
{
|
||||
LockContext(Context);
|
||||
Context->Listener.Position[0] = flValue1;
|
||||
Context->Listener.Position[1] = flValue2;
|
||||
Context->Listener.Position[2] = flValue3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
if(isfinite(flValue1) && isfinite(flValue2) && isfinite(flValue3))
|
||||
{
|
||||
LockContext(Context);
|
||||
Context->Listener.Velocity[0] = flValue1;
|
||||
Context->Listener.Velocity[1] = flValue2;
|
||||
Context->Listener.Velocity[2] = flValue3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListenerfv(ALenum eParam, const ALfloat *pflValues)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(pflValues)
|
||||
{
|
||||
switch(eParam)
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
case AL_METERS_PER_UNIT:
|
||||
alListenerf(eParam, pflValues[0]);
|
||||
return;
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(eParam, pflValues[0], pflValues[1], pflValues[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(pflValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_ORIENTATION:
|
||||
if(isfinite(pflValues[0]) && isfinite(pflValues[1]) &&
|
||||
isfinite(pflValues[2]) && isfinite(pflValues[3]) &&
|
||||
isfinite(pflValues[4]) && isfinite(pflValues[5]))
|
||||
{
|
||||
ALfloat U[3], V[3], N[3];
|
||||
|
||||
/* AT then UP */
|
||||
N[0] = pflValues[0];
|
||||
N[1] = pflValues[1];
|
||||
N[2] = pflValues[2];
|
||||
aluNormalize(N);
|
||||
V[0] = pflValues[3];
|
||||
V[1] = pflValues[4];
|
||||
V[2] = pflValues[5];
|
||||
aluNormalize(V);
|
||||
/* Build and normalize right-vector */
|
||||
aluCrossproduct(N, V, U);
|
||||
aluNormalize(U);
|
||||
|
||||
LockContext(Context);
|
||||
Context->Listener.Forward[0] = pflValues[0];
|
||||
Context->Listener.Forward[1] = pflValues[1];
|
||||
Context->Listener.Forward[2] = pflValues[2];
|
||||
Context->Listener.Up[0] = pflValues[3];
|
||||
Context->Listener.Up[1] = pflValues[4];
|
||||
Context->Listener.Up[2] = pflValues[5];
|
||||
Context->Listener.Matrix[0][0] = U[0];
|
||||
Context->Listener.Matrix[0][1] = V[0];
|
||||
Context->Listener.Matrix[0][2] = -N[0];
|
||||
Context->Listener.Matrix[0][3] = 0.0f;
|
||||
Context->Listener.Matrix[1][0] = U[1];
|
||||
Context->Listener.Matrix[1][1] = V[1];
|
||||
Context->Listener.Matrix[1][2] = -N[1];
|
||||
Context->Listener.Matrix[1][3] = 0.0f;
|
||||
Context->Listener.Matrix[2][0] = U[2];
|
||||
Context->Listener.Matrix[2][1] = V[2];
|
||||
Context->Listener.Matrix[2][2] = -N[2];
|
||||
Context->Listener.Matrix[2][3] = 0.0f;
|
||||
Context->Listener.Matrix[3][0] = 0.0f;
|
||||
Context->Listener.Matrix[3][1] = 0.0f;
|
||||
Context->Listener.Matrix[3][2] = 0.0f;
|
||||
Context->Listener.Matrix[3][3] = 1.0f;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListeneri(ALenum eParam, ALint lValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
(void)lValue;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListener3i(ALenum eParam, ALint lValue1, ALint lValue2, ALint lValue3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(eParam, (ALfloat)lValue1, (ALfloat)lValue2, (ALfloat)lValue3);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListeneriv( ALenum eParam, const ALint* plValues )
|
||||
{
|
||||
ALCcontext *Context;
|
||||
ALfloat flValues[6];
|
||||
|
||||
if(plValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(eParam, (ALfloat)plValues[0], (ALfloat)plValues[1], (ALfloat)plValues[2]);
|
||||
return;
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(plValues)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum eParam, ALfloat *pflValue)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(pflValue)
|
||||
{
|
||||
switch(eParam)
|
||||
{
|
||||
case AL_GAIN:
|
||||
*pflValue = Context->Listener.Gain;
|
||||
Context->Listener->Gain = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
*pflValue = Context->Listener.MetersPerUnit;
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
Context->Listener->MetersPerUnit = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum eParam, ALfloat *pflValue1, ALfloat *pflValue2, ALfloat *pflValue3)
|
||||
AL_API ALvoid AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(pflValue1 && pflValue2 && pflValue3)
|
||||
al_try
|
||||
{
|
||||
switch(eParam)
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
|
||||
|
||||
LockContext(Context);
|
||||
Context->Listener->Position[0] = value1;
|
||||
Context->Listener->Position[1] = value2;
|
||||
Context->Listener->Position[2] = value3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
CHECK_VALUE(Context, isfinite(value1) && isfinite(value2) && isfinite(value3));
|
||||
|
||||
LockContext(Context);
|
||||
Context->Listener->Velocity[0] = value1;
|
||||
Context->Listener->Velocity[1] = value2;
|
||||
Context->Listener->Velocity[2] = value3;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(values)
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
case AL_METERS_PER_UNIT:
|
||||
alListenerf(param, values[0]);
|
||||
return;
|
||||
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, values[0], values[1], values[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
case AL_ORIENTATION:
|
||||
CHECK_VALUE(Context, isfinite(values[0]) && isfinite(values[1]) &&
|
||||
isfinite(values[2]) && isfinite(values[3]) &&
|
||||
isfinite(values[4]) && isfinite(values[5]));
|
||||
|
||||
LockContext(Context);
|
||||
/* AT then UP */
|
||||
Context->Listener->Forward[0] = values[0];
|
||||
Context->Listener->Forward[1] = values[1];
|
||||
Context->Listener->Forward[2] = values[2];
|
||||
Context->Listener->Up[0] = values[3];
|
||||
Context->Listener->Up[1] = values[4];
|
||||
Context->Listener->Up[2] = values[5];
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alListeneri(ALenum param, ALint value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
(void)value;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(values)
|
||||
{
|
||||
ALfloat fvals[6];
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alListener3f(param, (ALfloat)values[0], (ALfloat)values[1], (ALfloat)values[2]);
|
||||
return;
|
||||
|
||||
case AL_ORIENTATION:
|
||||
fvals[0] = (ALfloat)values[0];
|
||||
fvals[1] = (ALfloat)values[1];
|
||||
fvals[2] = (ALfloat)values[2];
|
||||
fvals[3] = (ALfloat)values[3];
|
||||
fvals[4] = (ALfloat)values[4];
|
||||
fvals[5] = (ALfloat)values[5];
|
||||
alListenerfv(param, fvals);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, value);
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
*value = Context->Listener->Gain;
|
||||
break;
|
||||
|
||||
case AL_METERS_PER_UNIT:
|
||||
*value = Context->Listener->MetersPerUnit;
|
||||
break;
|
||||
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, value1 && value2 && value3);
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
LockContext(Context);
|
||||
*pflValue1 = Context->Listener.Position[0];
|
||||
*pflValue2 = Context->Listener.Position[1];
|
||||
*pflValue3 = Context->Listener.Position[2];
|
||||
*value1 = Context->Listener->Position[0];
|
||||
*value2 = Context->Listener->Position[1];
|
||||
*value3 = Context->Listener->Position[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
LockContext(Context);
|
||||
*pflValue1 = Context->Listener.Velocity[0];
|
||||
*pflValue2 = Context->Listener.Velocity[1];
|
||||
*pflValue3 = Context->Listener.Velocity[2];
|
||||
*value1 = Context->Listener->Velocity[0];
|
||||
*value2 = Context->Listener->Velocity[1];
|
||||
*value3 = Context->Listener->Velocity[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum eParam, ALfloat *pflValues)
|
||||
AL_API ALvoid AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(eParam)
|
||||
switch(param)
|
||||
{
|
||||
case AL_GAIN:
|
||||
case AL_METERS_PER_UNIT:
|
||||
alGetListenerf(eParam, pflValues);
|
||||
alGetListenerf(param, values);
|
||||
return;
|
||||
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alGetListener3f(eParam, pflValues+0, pflValues+1, pflValues+2);
|
||||
alGetListener3f(param, values+0, values+1, values+2);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(pflValues)
|
||||
al_try
|
||||
{
|
||||
switch(eParam)
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
case AL_ORIENTATION:
|
||||
LockContext(Context);
|
||||
// AT then UP
|
||||
pflValues[0] = Context->Listener.Forward[0];
|
||||
pflValues[1] = Context->Listener.Forward[1];
|
||||
pflValues[2] = Context->Listener.Forward[2];
|
||||
pflValues[3] = Context->Listener.Up[0];
|
||||
pflValues[4] = Context->Listener.Up[1];
|
||||
pflValues[5] = Context->Listener.Up[2];
|
||||
values[0] = Context->Listener->Forward[0];
|
||||
values[1] = Context->Listener->Forward[1];
|
||||
values[2] = Context->Listener->Forward[2];
|
||||
values[3] = Context->Listener->Up[0];
|
||||
values[4] = Context->Listener->Up[1];
|
||||
values[5] = Context->Listener->Up[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum eParam, ALint *plValue)
|
||||
AL_API ALvoid AL_APIENTRY alGetListeneri(ALenum param, ALint *value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(plValue)
|
||||
al_try
|
||||
{
|
||||
switch(eParam)
|
||||
CHECK_VALUE(Context, value);
|
||||
switch(param)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alGetListener3i(ALenum eParam, ALint *plValue1, ALint *plValue2, ALint *plValue3)
|
||||
AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(plValue1 && plValue2 && plValue3)
|
||||
al_try
|
||||
{
|
||||
switch (eParam)
|
||||
CHECK_VALUE(Context, value1 && value2 && value3);
|
||||
switch (param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
LockContext(Context);
|
||||
*plValue1 = (ALint)Context->Listener.Position[0];
|
||||
*plValue2 = (ALint)Context->Listener.Position[1];
|
||||
*plValue3 = (ALint)Context->Listener.Position[2];
|
||||
*value1 = (ALint)Context->Listener->Position[0];
|
||||
*value2 = (ALint)Context->Listener->Position[1];
|
||||
*value3 = (ALint)Context->Listener->Position[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
case AL_VELOCITY:
|
||||
LockContext(Context);
|
||||
*plValue1 = (ALint)Context->Listener.Velocity[0];
|
||||
*plValue2 = (ALint)Context->Listener.Velocity[1];
|
||||
*plValue3 = (ALint)Context->Listener.Velocity[2];
|
||||
*value1 = (ALint)Context->Listener->Velocity[0];
|
||||
*value2 = (ALint)Context->Listener->Velocity[1];
|
||||
*value3 = (ALint)Context->Listener->Velocity[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alGetListeneriv(ALenum eParam, ALint* plValues)
|
||||
AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint* values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
switch(eParam)
|
||||
switch(param)
|
||||
{
|
||||
case AL_POSITION:
|
||||
case AL_VELOCITY:
|
||||
alGetListener3i(eParam, plValues+0, plValues+1, plValues+2);
|
||||
alGetListener3i(param, values+0, values+1, values+2);
|
||||
return;
|
||||
}
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(plValues)
|
||||
al_try
|
||||
{
|
||||
switch(eParam)
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(param)
|
||||
{
|
||||
case AL_ORIENTATION:
|
||||
LockContext(Context);
|
||||
// AT then UP
|
||||
plValues[0] = (ALint)Context->Listener.Forward[0];
|
||||
plValues[1] = (ALint)Context->Listener.Forward[1];
|
||||
plValues[2] = (ALint)Context->Listener.Forward[2];
|
||||
plValues[3] = (ALint)Context->Listener.Up[0];
|
||||
plValues[4] = (ALint)Context->Listener.Up[1];
|
||||
plValues[5] = (ALint)Context->Listener.Up[2];
|
||||
values[0] = (ALint)Context->Listener->Forward[0];
|
||||
values[1] = (ALint)Context->Listener->Forward[1];
|
||||
values[2] = (ALint)Context->Listener->Forward[2];
|
||||
values[3] = (ALint)Context->Listener->Up[0];
|
||||
values[4] = (ALint)Context->Listener->Up[1];
|
||||
values[5] = (ALint)Context->Listener->Up[2];
|
||||
UnlockContext(Context);
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
+2102
-1448
File diff suppressed because it is too large
Load Diff
+225
-213
@@ -27,7 +27,7 @@
|
||||
#include "alError.h"
|
||||
#include "alSource.h"
|
||||
#include "alAuxEffectSlot.h"
|
||||
#include "alState.h"
|
||||
|
||||
|
||||
static const ALchar alVendor[] = "OpenAL Community";
|
||||
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
|
||||
@@ -48,17 +48,20 @@ AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(capability)
|
||||
al_try
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
Context->SourceDistanceModel = AL_TRUE;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
switch(capability)
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
Context->SourceDistanceModel = AL_TRUE;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -70,17 +73,20 @@ AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(capability)
|
||||
al_try
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
Context->SourceDistanceModel = AL_FALSE;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
switch(capability)
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
Context->SourceDistanceModel = AL_FALSE;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -93,16 +99,19 @@ AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
switch(capability)
|
||||
al_try
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
value = Context->SourceDistanceModel;
|
||||
break;
|
||||
switch(capability)
|
||||
{
|
||||
case AL_SOURCE_DISTANCE_MODEL:
|
||||
value = Context->SourceDistanceModel;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -117,36 +126,39 @@ AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return AL_FALSE;
|
||||
|
||||
switch(pname)
|
||||
al_try
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
if(Context->DopplerFactor != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
switch(pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
if(Context->DopplerFactor != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
if(Context->DopplerVelocity != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
if(Context->DopplerVelocity != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
if(Context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
if(Context->flSpeedOfSound != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
if(Context->SpeedOfSound != 0.0f)
|
||||
value = AL_TRUE;
|
||||
break;
|
||||
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = Context->DeferUpdates;
|
||||
break;
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = Context->DeferUpdates;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -161,32 +173,35 @@ AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return 0.0;
|
||||
|
||||
switch(pname)
|
||||
al_try
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (double)Context->DopplerFactor;
|
||||
break;
|
||||
switch(pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (ALdouble)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (double)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (ALdouble)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (double)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALdouble)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (double)Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (ALdouble)Context->SpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALdouble)Context->DeferUpdates;
|
||||
break;
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALdouble)Context->DeferUpdates;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -201,32 +216,35 @@ AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return 0.0f;
|
||||
|
||||
switch(pname)
|
||||
al_try
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = Context->DopplerFactor;
|
||||
break;
|
||||
switch(pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (float)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALfloat)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = Context->SpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALfloat)Context->DeferUpdates;
|
||||
break;
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALfloat)Context->DeferUpdates;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -241,43 +259,46 @@ AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return 0;
|
||||
|
||||
switch(pname)
|
||||
al_try
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
switch(pname)
|
||||
{
|
||||
case AL_DOPPLER_FACTOR:
|
||||
value = (ALint)Context->DopplerFactor;
|
||||
break;
|
||||
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
case AL_DOPPLER_VELOCITY:
|
||||
value = (ALint)Context->DopplerVelocity;
|
||||
break;
|
||||
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
case AL_DISTANCE_MODEL:
|
||||
value = (ALint)Context->DistanceModel;
|
||||
break;
|
||||
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (ALint)Context->flSpeedOfSound;
|
||||
break;
|
||||
case AL_SPEED_OF_SOUND:
|
||||
value = (ALint)Context->SpeedOfSound;
|
||||
break;
|
||||
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALint)Context->DeferUpdates;
|
||||
break;
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
value = (ALint)Context->DeferUpdates;
|
||||
break;
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
|
||||
AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(data)
|
||||
if(values)
|
||||
{
|
||||
switch(pname)
|
||||
{
|
||||
@@ -286,7 +307,7 @@ AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_SPEED_OF_SOUND:
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
*data = alGetBoolean(pname);
|
||||
values[0] = alGetBoolean(pname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -294,29 +315,25 @@ AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname,ALboolean *data)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(pname)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data)
|
||||
AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(data)
|
||||
if(values)
|
||||
{
|
||||
switch(pname)
|
||||
{
|
||||
@@ -325,7 +342,7 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data)
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_SPEED_OF_SOUND:
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
*data = alGetDouble(pname);
|
||||
values[0] = alGetDouble(pname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -333,29 +350,25 @@ AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname,ALdouble *data)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(pname)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data)
|
||||
AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(data)
|
||||
if(values)
|
||||
{
|
||||
switch(pname)
|
||||
{
|
||||
@@ -364,7 +377,7 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data)
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_SPEED_OF_SOUND:
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
*data = alGetFloat(pname);
|
||||
values[0] = alGetFloat(pname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -372,29 +385,25 @@ AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname,ALfloat *data)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(pname)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data)
|
||||
AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
if(data)
|
||||
if(values)
|
||||
{
|
||||
switch(pname)
|
||||
{
|
||||
@@ -403,7 +412,7 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data)
|
||||
case AL_DISTANCE_MODEL:
|
||||
case AL_SPEED_OF_SOUND:
|
||||
case AL_DEFERRED_UPDATES_SOFT:
|
||||
*data = alGetInteger(pname);
|
||||
values[0] = alGetInteger(pname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -411,20 +420,16 @@ AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname,ALint *data)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(data)
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, values);
|
||||
switch(pname)
|
||||
{
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// data is a NULL pointer
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -437,53 +442,59 @@ AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return NULL;
|
||||
|
||||
switch(pname)
|
||||
al_try
|
||||
{
|
||||
case AL_VENDOR:
|
||||
value=alVendor;
|
||||
break;
|
||||
switch(pname)
|
||||
{
|
||||
case AL_VENDOR:
|
||||
value = alVendor;
|
||||
break;
|
||||
|
||||
case AL_VERSION:
|
||||
value=alVersion;
|
||||
break;
|
||||
case AL_VERSION:
|
||||
value = alVersion;
|
||||
break;
|
||||
|
||||
case AL_RENDERER:
|
||||
value=alRenderer;
|
||||
break;
|
||||
case AL_RENDERER:
|
||||
value = alRenderer;
|
||||
break;
|
||||
|
||||
case AL_EXTENSIONS:
|
||||
value=Context->ExtensionList;
|
||||
break;
|
||||
case AL_EXTENSIONS:
|
||||
value = Context->ExtensionList;
|
||||
break;
|
||||
|
||||
case AL_NO_ERROR:
|
||||
value=alNoError;
|
||||
break;
|
||||
case AL_NO_ERROR:
|
||||
value = alNoError;
|
||||
break;
|
||||
|
||||
case AL_INVALID_NAME:
|
||||
value=alErrInvalidName;
|
||||
break;
|
||||
case AL_INVALID_NAME:
|
||||
value = alErrInvalidName;
|
||||
break;
|
||||
|
||||
case AL_INVALID_ENUM:
|
||||
value=alErrInvalidEnum;
|
||||
break;
|
||||
case AL_INVALID_ENUM:
|
||||
value = alErrInvalidEnum;
|
||||
break;
|
||||
|
||||
case AL_INVALID_VALUE:
|
||||
value=alErrInvalidValue;
|
||||
break;
|
||||
case AL_INVALID_VALUE:
|
||||
value = alErrInvalidValue;
|
||||
break;
|
||||
|
||||
case AL_INVALID_OPERATION:
|
||||
value=alErrInvalidOp;
|
||||
break;
|
||||
case AL_INVALID_OPERATION:
|
||||
value = alErrInvalidOp;
|
||||
break;
|
||||
|
||||
case AL_OUT_OF_MEMORY:
|
||||
value=alErrOutOfMemory;
|
||||
break;
|
||||
case AL_OUT_OF_MEMORY:
|
||||
value = alErrOutOfMemory;
|
||||
break;
|
||||
|
||||
default:
|
||||
value=NULL;
|
||||
alSetError(Context, AL_INVALID_ENUM);
|
||||
break;
|
||||
default:
|
||||
al_throwerr(Context, AL_INVALID_ENUM);
|
||||
}
|
||||
}
|
||||
al_catchany()
|
||||
{
|
||||
value = NULL;
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
|
||||
@@ -497,13 +508,14 @@ AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(value >= 0.0f && isfinite(value))
|
||||
al_try
|
||||
{
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
Context->DopplerFactor = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -515,31 +527,33 @@ AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(value > 0.0f && isfinite(value))
|
||||
al_try
|
||||
{
|
||||
Context->DopplerVelocity=value;
|
||||
CHECK_VALUE(Context, value >= 0.0f && isfinite(value));
|
||||
|
||||
Context->DopplerVelocity = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat flSpeedOfSound)
|
||||
AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
|
||||
{
|
||||
ALCcontext *Context;
|
||||
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
if(flSpeedOfSound > 0.0f && isfinite(flSpeedOfSound))
|
||||
al_try
|
||||
{
|
||||
Context->flSpeedOfSound = flSpeedOfSound;
|
||||
CHECK_VALUE(Context, value > 0.0f && isfinite(value));
|
||||
|
||||
Context->SpeedOfSound = value;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
else
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -551,23 +565,21 @@ AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
|
||||
Context = GetContextRef();
|
||||
if(!Context) return;
|
||||
|
||||
switch(value)
|
||||
al_try
|
||||
{
|
||||
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;
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
break;
|
||||
CHECK_VALUE(Context, value == AL_NONE ||
|
||||
value == AL_INVERSE_DISTANCE ||
|
||||
value == AL_INVERSE_DISTANCE_CLAMPED ||
|
||||
value == AL_LINEAR_DISTANCE ||
|
||||
value == AL_LINEAR_DISTANCE_CLAMPED ||
|
||||
value == AL_EXPONENT_DISTANCE ||
|
||||
value == AL_EXPONENT_DISTANCE_CLAMPED);
|
||||
|
||||
default:
|
||||
alSetError(Context, AL_INVALID_VALUE);
|
||||
break;
|
||||
Context->DistanceModel = value;
|
||||
if(!Context->SourceDistanceModel)
|
||||
Context->UpdateSources = AL_TRUE;
|
||||
}
|
||||
al_endtry;
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
}
|
||||
@@ -585,9 +597,9 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
|
||||
ALboolean UpdateSources;
|
||||
ALsource **src, **src_end;
|
||||
ALeffectslot **slot, **slot_end;
|
||||
int fpuState;
|
||||
FPUCtl oldMode;
|
||||
|
||||
fpuState = SetMixerFPUMode();
|
||||
SetMixerFPUMode(&oldMode);
|
||||
|
||||
LockContext(Context);
|
||||
Context->DeferUpdates = AL_TRUE;
|
||||
@@ -622,7 +634,7 @@ AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
|
||||
}
|
||||
|
||||
UnlockContext(Context);
|
||||
RestoreFPUMode(fpuState);
|
||||
RestoreFPUMode(&oldMode);
|
||||
}
|
||||
|
||||
ALCcontext_DecRef(Context);
|
||||
@@ -647,7 +659,7 @@ AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
|
||||
ALenum new_state;
|
||||
|
||||
if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
|
||||
Source->lOffset != -1)
|
||||
Source->Offset >= 0.0)
|
||||
ApplyOffset(Source);
|
||||
|
||||
new_state = ExchangeInt(&Source->new_state, AL_NONE);
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ ALenum NewThunkEntry(ALuint *index)
|
||||
if(!NewList)
|
||||
{
|
||||
WriteUnlock(&ThunkLock);
|
||||
ERR("Realloc failed to increase to %u enties!\n", ThunkArraySize*2);
|
||||
ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2);
|
||||
return AL_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(&NewList[ThunkArraySize], 0, ThunkArraySize*sizeof(*ThunkArray));
|
||||
|
||||
+32
-17
@@ -11,6 +11,13 @@
|
||||
# possible). Note: options that are left unset may default to app- or system-
|
||||
# specified values. These are the current available settings:
|
||||
|
||||
## disable-cpu-exts:
|
||||
# Disables use of the listed CPU extensions. Certain methods may utilize CPU
|
||||
# extensions when detected, and this option is useful for preventing those
|
||||
# extensions from being used. The available extensions are: sse, neon.
|
||||
# Specifying 'all' disables use of all extensions.
|
||||
#disable-cpu-exts =
|
||||
|
||||
## channels:
|
||||
# Sets the output channel configuration. If left unspecified, one will try to
|
||||
# be detected from the system, and defaulting to stereo. The available values
|
||||
@@ -39,7 +46,13 @@
|
||||
## hrtf_tables
|
||||
# Specifies a comma-separated list of files containing HRTF data sets. The
|
||||
# listed data sets can be used in place of or in addiiton to the the built-in
|
||||
# set. The format of the files are described in hrtf.txt.
|
||||
# set. The format of the files are described in hrtf.txt. The filenames may
|
||||
# contain these markers, which will be replaced as needed:
|
||||
# %r - Device sampling rate
|
||||
# %% - Percent sign (%)
|
||||
# So if this is set to "kemar-%r-diffuse.mhr", it will try to open
|
||||
# "kemar-44100-diffuse.mhr" if the device is using 44100hz output, or
|
||||
# "kemar-48000-diffuse.mhr" if the device is using 48000hz output, etc.
|
||||
#hrtf_tables =
|
||||
|
||||
## cf_level:
|
||||
@@ -55,6 +68,14 @@
|
||||
# stereo modes.
|
||||
#cf_level = 0
|
||||
|
||||
## wide-stereo:
|
||||
# Specifies that stereo sources are given a width of about 120 degrees on each
|
||||
# channel, centering on -90 (left) and +90 (right), as opposed to being points
|
||||
# placed at -30 (left) and +30 (right). This can be useful for surround-sound
|
||||
# to give stereo sources a more encompassing sound. Note that the sound's
|
||||
# overall volume will be slightly reduced to account for the extra output.
|
||||
#wide-stereo = false
|
||||
|
||||
## frequency:
|
||||
# Sets the output frequency.
|
||||
#frequency = 44100
|
||||
@@ -93,16 +114,6 @@
|
||||
# systems with apps that try to play more sounds than the CPU can handle.
|
||||
#sources = 256
|
||||
|
||||
## stereodup:
|
||||
# Sets whether to duplicate stereo sounds behind the listener. This provides a
|
||||
# "fuller" playback quality for surround sound output modes, although each
|
||||
# individual speaker will have a slight reduction in volume to compensate for
|
||||
# the extra output speakers. True, yes, on, and non-0 values will duplicate
|
||||
# stereo sources. 0 and anything else will cause stereo sounds to only play in
|
||||
# front. This only has an effect when a suitable output format is used (ie.
|
||||
# those that contain side and/or rear speakers).
|
||||
#stereodup = true
|
||||
|
||||
## drivers:
|
||||
# Sets the backend driver list order, comma-seperated. Unknown backends and
|
||||
# duplicated names are ignored. Unlisted backends won't be considered for use
|
||||
@@ -210,7 +221,7 @@
|
||||
# option. The option may specify the card id (eg, device-prefix-NVidia), or
|
||||
# the card id and device index (eg, device-prefix-NVidia-0). The card id is
|
||||
# case-sensitive.
|
||||
#defice-prefix- =
|
||||
#device-prefix- =
|
||||
|
||||
## capture:
|
||||
# Sets the device name for the default capture device.
|
||||
@@ -295,11 +306,15 @@
|
||||
|
||||
## spawn-server:
|
||||
# Attempts to spawn a PulseAudio server when requesting to open a PulseAudio
|
||||
# device. Note that some apps may open and probe all enumerated devices on
|
||||
# startup, causing a server to spawn even if a PulseAudio device is not
|
||||
# actually selected. Setting autospawn to false in Pulse's client.conf will
|
||||
# still prevent autospawning even if this is set to true.
|
||||
#spawn-server = false
|
||||
# device. Setting autospawn to false in PulseAudio's client.conf will still
|
||||
# prevent autospawning even if this is set to true.
|
||||
#spawn-server = true
|
||||
|
||||
## allow-moves:
|
||||
# Allows PulseAudio to move active streams to different devices. Note that the
|
||||
# device specifier seen by applications will not be updated when this occurs,
|
||||
# and neither will the AL device configuration (sample rate, format, etc).
|
||||
#allow-moves = false
|
||||
|
||||
##
|
||||
## Wave File Writer stuff
|
||||
|
||||
+48
-48
@@ -5,6 +5,30 @@
|
||||
/* Define to the library version */
|
||||
#define ALSOFT_VERSION "${LIB_VERSION}"
|
||||
|
||||
/* Define any available alignment declaration */
|
||||
#define ALIGN(x) ${ALIGN_DECL}
|
||||
#ifdef __MINGW32__
|
||||
#define align(x) aligned(x)
|
||||
#endif
|
||||
|
||||
/* Define to the appropriate 'restrict' keyword */
|
||||
#define RESTRICT ${RESTRICT_DECL}
|
||||
|
||||
/* Define if we have the C11 aligned_alloc function */
|
||||
#cmakedefine HAVE_ALIGNED_ALLOC
|
||||
|
||||
/* Define if we have the posix_memalign function */
|
||||
#cmakedefine HAVE_POSIX_MEMALIGN
|
||||
|
||||
/* Define if we have the _aligned_malloc function */
|
||||
#cmakedefine HAVE__ALIGNED_MALLOC
|
||||
|
||||
/* Define if we have SSE CPU extensions */
|
||||
#cmakedefine HAVE_SSE
|
||||
|
||||
/* Define if we have ARM Neon CPU extensions */
|
||||
#cmakedefine HAVE_NEON
|
||||
|
||||
/* Define if we have the ALSA backend */
|
||||
#cmakedefine HAVE_ALSA
|
||||
|
||||
@@ -41,51 +65,15 @@
|
||||
/* Define if we have the Wave Writer backend */
|
||||
#cmakedefine HAVE_WAVE
|
||||
|
||||
/* Define if we have dlfcn.h */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
|
||||
/* Define if we have the stat function */
|
||||
#cmakedefine HAVE_STAT
|
||||
|
||||
/* Define if we have the powf function */
|
||||
#cmakedefine HAVE_POWF
|
||||
|
||||
/* Define if we have the sqrtf function */
|
||||
#cmakedefine HAVE_SQRTF
|
||||
|
||||
/* Define if we have the cosf function */
|
||||
#cmakedefine HAVE_COSF
|
||||
|
||||
/* Define if we have the sinf function */
|
||||
#cmakedefine HAVE_SINF
|
||||
|
||||
/* Define if we have the acosf function */
|
||||
#cmakedefine HAVE_ACOSF
|
||||
|
||||
/* Define if we have the asinf function */
|
||||
#cmakedefine HAVE_ASINF
|
||||
|
||||
/* Define if we have the atanf function */
|
||||
#cmakedefine HAVE_ATANF
|
||||
|
||||
/* Define if we have the atan2f function */
|
||||
#cmakedefine HAVE_ATAN2F
|
||||
|
||||
/* Define if we have the fabsf function */
|
||||
#cmakedefine HAVE_FABSF
|
||||
|
||||
/* Define if we have the log10f function */
|
||||
#cmakedefine HAVE_LOG10F
|
||||
|
||||
/* Define if we have the floorf function */
|
||||
#cmakedefine HAVE_FLOORF
|
||||
/* Define if we have the lrintf function */
|
||||
#cmakedefine HAVE_LRINTF
|
||||
|
||||
/* Define if we have the strtof function */
|
||||
#cmakedefine HAVE_STRTOF
|
||||
|
||||
/* Define if we have stdint.h */
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
/* Define if we have the __int64 type */
|
||||
#cmakedefine HAVE___INT64
|
||||
|
||||
@@ -101,16 +89,34 @@
|
||||
/* Define if we have GCC's format attribute */
|
||||
#cmakedefine HAVE_GCC_FORMAT
|
||||
|
||||
/* Define if we have stdint.h */
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
|
||||
/* Define if we have windows.h */
|
||||
#cmakedefine HAVE_WINDOWS_H
|
||||
|
||||
/* Define if we have dlfcn.h */
|
||||
#cmakedefine HAVE_DLFCN_H
|
||||
|
||||
/* Define if we have pthread_np.h */
|
||||
#cmakedefine HAVE_PTHREAD_NP_H
|
||||
|
||||
/* Define if we have xmmintrin.h */
|
||||
#cmakedefine HAVE_XMMINTRIN_H
|
||||
|
||||
/* Define if we have arm_neon.h */
|
||||
#cmakedefine HAVE_ARM_NEON_H
|
||||
|
||||
/* Define if we have malloc.h */
|
||||
#cmakedefine HAVE_MALLOC_H
|
||||
|
||||
/* Define if we have cpuid.h */
|
||||
#cmakedefine HAVE_CPUID_H
|
||||
|
||||
/* Define if we have guiddef.h */
|
||||
#cmakedefine HAVE_GUIDDEF_H
|
||||
|
||||
/* Define if we have guiddef.h */
|
||||
/* Define if we have initguid.h */
|
||||
#cmakedefine HAVE_INITGUID_H
|
||||
|
||||
/* Define if we have ieeefp.h */
|
||||
@@ -119,9 +125,6 @@
|
||||
/* Define if we have float.h */
|
||||
#cmakedefine HAVE_FLOAT_H
|
||||
|
||||
/* Define if we have fpu_control.h */
|
||||
#cmakedefine HAVE_FPU_CONTROL_H
|
||||
|
||||
/* Define if we have fenv.h */
|
||||
#cmakedefine HAVE_FENV_H
|
||||
|
||||
@@ -131,11 +134,8 @@
|
||||
/* Define if we have _controlfp() */
|
||||
#cmakedefine HAVE__CONTROLFP
|
||||
|
||||
/* Define if we have __control87_2() */
|
||||
#cmakedefine HAVE___CONTROL87_2
|
||||
|
||||
/* Define if we have pthread_setschedparam() */
|
||||
#cmakedefine HAVE_PTHREAD_SETSCHEDPARAM
|
||||
|
||||
/* Define if we have the restrict keyword */
|
||||
#cmakedefine HAVE_RESTRICT
|
||||
|
||||
/* Define if we have the __restrict keyword */
|
||||
#cmakedefine HAVE___RESTRICT
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* OpenAL Source Latency Example
|
||||
*
|
||||
* Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This file contains an example for checking the latency of a sound. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define Sleep(x) usleep((x)*1000)
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
|
||||
|
||||
LPALSOURCEDSOFT alSourcedSOFT;
|
||||
LPALSOURCE3DSOFT alSource3dSOFT;
|
||||
LPALSOURCEDVSOFT alSourcedvSOFT;
|
||||
LPALGETSOURCEDSOFT alGetSourcedSOFT;
|
||||
LPALGETSOURCE3DSOFT alGetSource3dSOFT;
|
||||
LPALGETSOURCEDVSOFT alGetSourcedvSOFT;
|
||||
LPALSOURCEI64SOFT alSourcei64SOFT;
|
||||
LPALSOURCE3I64SOFT alSource3i64SOFT;
|
||||
LPALSOURCEI64VSOFT alSourcei64vSOFT;
|
||||
LPALGETSOURCEI64SOFT alGetSourcei64SOFT;
|
||||
LPALGETSOURCE3I64SOFT alGetSource3i64SOFT;
|
||||
LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
|
||||
|
||||
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
|
||||
* returns the new buffer ID. */
|
||||
static ALuint LoadSound(const char *filename)
|
||||
{
|
||||
ALenum err, format, type, channels;
|
||||
ALuint rate, buffer;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
FilePtr audiofile;
|
||||
StreamPtr sound;
|
||||
|
||||
/* Open the file and get the first stream from it */
|
||||
audiofile = openAVFile(filename);
|
||||
sound = getAVAudioStream(audiofile, 0);
|
||||
if(!sound)
|
||||
{
|
||||
fprintf(stderr, "Could not open audio in %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the sound format, and figure out the OpenAL format */
|
||||
if(getAVAudioInfo(sound, &rate, &channels, &type) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting audio info for %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
ChannelsName(channels), TypeName(type), filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the whole audio stream to a buffer. */
|
||||
data = decodeAVAudioStream(sound, &datalen);
|
||||
if(!data)
|
||||
{
|
||||
fprintf(stderr, "Failed to read audio from %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Buffer the audio data into a new buffer object, then free the data and
|
||||
* close the file. */
|
||||
buffer = 0;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
|
||||
channels, type, data);
|
||||
free(data);
|
||||
closeAVFile(audiofile);
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
|
||||
if(alIsBuffer(buffer))
|
||||
alDeleteBuffers(1, &buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ALuint source, buffer;
|
||||
ALdouble offsets[2];
|
||||
ALenum state;
|
||||
|
||||
/* Print out usage if no file was specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize OpenAL with the default device, and check for EFX support. */
|
||||
if(InitAL() != 0)
|
||||
return 1;
|
||||
|
||||
if(!alIsExtensionPresent("AL_SOFT_source_latency"))
|
||||
{
|
||||
fprintf(stderr, "Error: AL_SOFT_source_latency not supported\n");
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Define a macro to help load the function pointers. */
|
||||
#define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
|
||||
LOAD_PROC(alSourcedSOFT);
|
||||
LOAD_PROC(alSource3dSOFT);
|
||||
LOAD_PROC(alSourcedvSOFT);
|
||||
LOAD_PROC(alGetSourcedSOFT);
|
||||
LOAD_PROC(alGetSource3dSOFT);
|
||||
LOAD_PROC(alGetSourcedvSOFT);
|
||||
LOAD_PROC(alSourcei64SOFT);
|
||||
LOAD_PROC(alSource3i64SOFT);
|
||||
LOAD_PROC(alSourcei64vSOFT);
|
||||
LOAD_PROC(alGetSourcei64SOFT);
|
||||
LOAD_PROC(alGetSource3i64SOFT);
|
||||
LOAD_PROC(alGetSourcei64vSOFT);
|
||||
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
LOAD_PROC(alBufferSamplesSOFT);
|
||||
LOAD_PROC(alIsBufferFormatSupportedSOFT);
|
||||
}
|
||||
#undef LOAD_PROC
|
||||
|
||||
/* Load the sound into a buffer. */
|
||||
buffer = LoadSound(argv[1]);
|
||||
if(!buffer)
|
||||
{
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the source to play the sound with. */
|
||||
source = 0;
|
||||
alGenSources(1, &source);
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
|
||||
|
||||
/* Play the sound until it finishes. */
|
||||
alSourcePlay(source);
|
||||
do {
|
||||
Sleep(10);
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
|
||||
/* Get the source offset and latency. AL_SEC_OFFSET_LATENCY_SOFT will
|
||||
* place the offset (in seconds) in offsets[0], and the time until that
|
||||
* offset will be heard (in seconds) in offsets[1]. */
|
||||
alGetSourcedvSOFT(source, AL_SEC_OFFSET_LATENCY_SOFT, offsets);
|
||||
printf("\rOffset: %f - Latency:%3u ms ", offsets[0], (ALuint)(offsets[1]*1000));
|
||||
fflush(stdout);
|
||||
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
|
||||
printf("\n");
|
||||
|
||||
/* All done. Delete resources, and close OpenAL. */
|
||||
alDeleteSources(1, &source);
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
CloseAL();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* OpenAL Reverb Example
|
||||
*
|
||||
* Copyright (c) 2012 by Chris Robinson <chris.kcat@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* This file contains an example for applying reverb to a sound. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define Sleep(x) usleep((x)*1000)
|
||||
#endif
|
||||
|
||||
#include "AL/al.h"
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
#include "AL/efx-presets.h"
|
||||
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
|
||||
|
||||
/* Effect object functions */
|
||||
LPALGENEFFECTS alGenEffects;
|
||||
LPALDELETEEFFECTS alDeleteEffects;
|
||||
LPALISEFFECT alIsEffect;
|
||||
LPALEFFECTI alEffecti;
|
||||
LPALEFFECTIV alEffectiv;
|
||||
LPALEFFECTF alEffectf;
|
||||
LPALEFFECTFV alEffectfv;
|
||||
LPALGETEFFECTI alGetEffecti;
|
||||
LPALGETEFFECTIV alGetEffectiv;
|
||||
LPALGETEFFECTF alGetEffectf;
|
||||
LPALGETEFFECTFV alGetEffectfv;
|
||||
|
||||
/* Auxiliary Effect Slot object functions */
|
||||
LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots;
|
||||
LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots;
|
||||
LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot;
|
||||
LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti;
|
||||
LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv;
|
||||
LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf;
|
||||
LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv;
|
||||
LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti;
|
||||
LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv;
|
||||
LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf;
|
||||
LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv;
|
||||
|
||||
|
||||
/* LoadEffect loads the given reverb properties into a new OpenAL effect
|
||||
* object, and returns the new effect ID. */
|
||||
static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb)
|
||||
{
|
||||
ALuint effect = 0;
|
||||
ALenum err;
|
||||
|
||||
/* Create the effect object and check if we can do EAX reverb. */
|
||||
alGenEffects(1, &effect);
|
||||
if(alGetEnumValue("AL_EFFECT_EAXREVERB") != 0)
|
||||
{
|
||||
printf("Using EAX Reverb\n");
|
||||
|
||||
/* EAX Reverb is available. Set the EAX effect type then load the
|
||||
* reverb properties. */
|
||||
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
|
||||
alEffectf(effect, AL_EAXREVERB_DENSITY, reverb->flDensity);
|
||||
alEffectf(effect, AL_EAXREVERB_DIFFUSION, reverb->flDiffusion);
|
||||
alEffectf(effect, AL_EAXREVERB_GAIN, reverb->flGain);
|
||||
alEffectf(effect, AL_EAXREVERB_GAINHF, reverb->flGainHF);
|
||||
alEffectf(effect, AL_EAXREVERB_GAINLF, reverb->flGainLF);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_TIME, reverb->flDecayTime);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_HFRATIO, reverb->flDecayHFRatio);
|
||||
alEffectf(effect, AL_EAXREVERB_DECAY_LFRATIO, reverb->flDecayLFRatio);
|
||||
alEffectf(effect, AL_EAXREVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain);
|
||||
alEffectf(effect, AL_EAXREVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay);
|
||||
alEffectfv(effect, AL_EAXREVERB_REFLECTIONS_PAN, reverb->flReflectionsPan);
|
||||
alEffectf(effect, AL_EAXREVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain);
|
||||
alEffectf(effect, AL_EAXREVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay);
|
||||
alEffectfv(effect, AL_EAXREVERB_LATE_REVERB_PAN, reverb->flLateReverbPan);
|
||||
alEffectf(effect, AL_EAXREVERB_ECHO_TIME, reverb->flEchoTime);
|
||||
alEffectf(effect, AL_EAXREVERB_ECHO_DEPTH, reverb->flEchoDepth);
|
||||
alEffectf(effect, AL_EAXREVERB_MODULATION_TIME, reverb->flModulationTime);
|
||||
alEffectf(effect, AL_EAXREVERB_MODULATION_DEPTH, reverb->flModulationDepth);
|
||||
alEffectf(effect, AL_EAXREVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF);
|
||||
alEffectf(effect, AL_EAXREVERB_HFREFERENCE, reverb->flHFReference);
|
||||
alEffectf(effect, AL_EAXREVERB_LFREFERENCE, reverb->flLFReference);
|
||||
alEffectf(effect, AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor);
|
||||
alEffecti(effect, AL_EAXREVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Using Standard Reverb\n");
|
||||
|
||||
/* No EAX Reverb. Set the standard reverb effect type then load the
|
||||
* available reverb properties. */
|
||||
alEffecti(effect, AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
|
||||
alEffectf(effect, AL_REVERB_DENSITY, reverb->flDensity);
|
||||
alEffectf(effect, AL_REVERB_DIFFUSION, reverb->flDiffusion);
|
||||
alEffectf(effect, AL_REVERB_GAIN, reverb->flGain);
|
||||
alEffectf(effect, AL_REVERB_GAINHF, reverb->flGainHF);
|
||||
alEffectf(effect, AL_REVERB_DECAY_TIME, reverb->flDecayTime);
|
||||
alEffectf(effect, AL_REVERB_DECAY_HFRATIO, reverb->flDecayHFRatio);
|
||||
alEffectf(effect, AL_REVERB_REFLECTIONS_GAIN, reverb->flReflectionsGain);
|
||||
alEffectf(effect, AL_REVERB_REFLECTIONS_DELAY, reverb->flReflectionsDelay);
|
||||
alEffectf(effect, AL_REVERB_LATE_REVERB_GAIN, reverb->flLateReverbGain);
|
||||
alEffectf(effect, AL_REVERB_LATE_REVERB_DELAY, reverb->flLateReverbDelay);
|
||||
alEffectf(effect, AL_REVERB_AIR_ABSORPTION_GAINHF, reverb->flAirAbsorptionGainHF);
|
||||
alEffectf(effect, AL_REVERB_ROOM_ROLLOFF_FACTOR, reverb->flRoomRolloffFactor);
|
||||
alEffecti(effect, AL_REVERB_DECAY_HFLIMIT, reverb->iDecayHFLimit);
|
||||
}
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL error: %s\n", alGetString(err));
|
||||
if(alIsEffect(effect))
|
||||
alDeleteEffects(1, &effect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return effect;
|
||||
}
|
||||
|
||||
|
||||
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
|
||||
* returns the new buffer ID. */
|
||||
static ALuint LoadSound(const char *filename)
|
||||
{
|
||||
ALenum err, format, type, channels;
|
||||
ALuint rate, buffer;
|
||||
size_t datalen;
|
||||
void *data;
|
||||
FilePtr audiofile;
|
||||
StreamPtr sound;
|
||||
|
||||
/* Open the file and get the first stream from it */
|
||||
audiofile = openAVFile(filename);
|
||||
sound = getAVAudioStream(audiofile, 0);
|
||||
if(!sound)
|
||||
{
|
||||
fprintf(stderr, "Could not open audio in %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the sound format, and figure out the OpenAL format */
|
||||
if(getAVAudioInfo(sound, &rate, &channels, &type) != 0)
|
||||
{
|
||||
fprintf(stderr, "Error getting audio info for %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
|
||||
if(format == AL_NONE)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
ChannelsName(channels), TypeName(type), filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decode the whole audio stream to a buffer. */
|
||||
data = decodeAVAudioStream(sound, &datalen);
|
||||
if(!data)
|
||||
{
|
||||
fprintf(stderr, "Failed to read audio from %s\n", filename);
|
||||
closeAVFile(audiofile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Buffer the audio data into a new buffer object, then free the data and
|
||||
* close the file. */
|
||||
buffer = 0;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
|
||||
channels, type, data);
|
||||
free(data);
|
||||
closeAVFile(audiofile);
|
||||
|
||||
/* Check if an error occured, and clean up if so. */
|
||||
err = alGetError();
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
|
||||
if(alIsBuffer(buffer))
|
||||
alDeleteBuffers(1, &buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
EFXEAXREVERBPROPERTIES reverb = EFX_REVERB_PRESET_GENERIC;
|
||||
ALuint source, buffer, effect, slot;
|
||||
ALenum state;
|
||||
|
||||
/* Print out usage if no file was specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Initialize OpenAL with the default device, and check for EFX support. */
|
||||
if(InitAL() != 0)
|
||||
return 1;
|
||||
|
||||
if(!alcIsExtensionPresent(alcGetContextsDevice(alcGetCurrentContext()), "ALC_EXT_EFX"))
|
||||
{
|
||||
fprintf(stderr, "Error: EFX not supported\n");
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Define a macro to help load the function pointers. */
|
||||
#define LOAD_PROC(x) ((x) = alGetProcAddress(#x))
|
||||
LOAD_PROC(alGenEffects);
|
||||
LOAD_PROC(alDeleteEffects);
|
||||
LOAD_PROC(alIsEffect);
|
||||
LOAD_PROC(alEffecti);
|
||||
LOAD_PROC(alEffectiv);
|
||||
LOAD_PROC(alEffectf);
|
||||
LOAD_PROC(alEffectfv);
|
||||
LOAD_PROC(alGetEffecti);
|
||||
LOAD_PROC(alGetEffectiv);
|
||||
LOAD_PROC(alGetEffectf);
|
||||
LOAD_PROC(alGetEffectfv);
|
||||
|
||||
LOAD_PROC(alGenAuxiliaryEffectSlots);
|
||||
LOAD_PROC(alDeleteAuxiliaryEffectSlots);
|
||||
LOAD_PROC(alIsAuxiliaryEffectSlot);
|
||||
LOAD_PROC(alAuxiliaryEffectSloti);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotiv);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotf);
|
||||
LOAD_PROC(alAuxiliaryEffectSlotfv);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSloti);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotiv);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotf);
|
||||
LOAD_PROC(alGetAuxiliaryEffectSlotfv);
|
||||
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
LOAD_PROC(alBufferSamplesSOFT);
|
||||
LOAD_PROC(alIsBufferFormatSupportedSOFT);
|
||||
}
|
||||
#undef LOAD_PROC
|
||||
|
||||
/* Load the sound into a buffer. */
|
||||
buffer = LoadSound(argv[1]);
|
||||
if(!buffer)
|
||||
{
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load the reverb into an effect. */
|
||||
effect = LoadEffect(&reverb);
|
||||
if(!effect)
|
||||
{
|
||||
alDeleteBuffers(1, &buffer);
|
||||
CloseAL();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create the effect slot object. This is what "plays" an effect on sources
|
||||
* that connect to it. */
|
||||
slot = 0;
|
||||
alGenAuxiliaryEffectSlots(1, &slot);
|
||||
|
||||
/* Tell the effect slot to use the loaded effect object. Note that the this
|
||||
* effectively copies the effect properties. You can modify or delete the
|
||||
* effect object afterward without affecting the effect slot.
|
||||
*/
|
||||
alAuxiliaryEffectSloti(slot, AL_EFFECTSLOT_EFFECT, effect);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to set effect slot");
|
||||
|
||||
/* Create the source to play the sound with. */
|
||||
source = 0;
|
||||
alGenSources(1, &source);
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
/* Connect the source to the effect slot. This tells the source to use the
|
||||
* effect slot 'slot', on send #0 with the AL_FILTER_NULL filter object.
|
||||
*/
|
||||
alSource3i(source, AL_AUXILIARY_SEND_FILTER, slot, 0, AL_FILTER_NULL);
|
||||
assert(alGetError()==AL_NO_ERROR && "Failed to setup sound source");
|
||||
|
||||
/* Play the sound until it finishes. */
|
||||
alSourcePlay(source);
|
||||
do {
|
||||
Sleep(10);
|
||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
||||
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
|
||||
|
||||
/* All done. Delete resources, and close OpenAL. */
|
||||
alDeleteSources(1, &source);
|
||||
alDeleteAuxiliaryEffectSlots(1, &slot);
|
||||
alDeleteEffects(1, &effect);
|
||||
alDeleteBuffers(1, &buffer);
|
||||
|
||||
CloseAL();
|
||||
|
||||
return 0;
|
||||
}
|
||||
+18
-17
@@ -34,12 +34,12 @@
|
||||
#include "AL/alc.h"
|
||||
#include "AL/alext.h"
|
||||
|
||||
#include "alhelpers.h"
|
||||
#include "alffmpeg.h"
|
||||
#include "common/alhelpers.h"
|
||||
#include "common/alffmpeg.h"
|
||||
|
||||
|
||||
LPALBUFFERSAMPLESSOFT palBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT = NULL;
|
||||
LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
|
||||
LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT = NULL;
|
||||
|
||||
|
||||
/* Define the number of buffers and buffer size (in samples) to use. 4 buffers
|
||||
@@ -144,7 +144,7 @@ static int OpenPlayerFile(StreamPlayer *player, const char *filename)
|
||||
goto error;
|
||||
}
|
||||
|
||||
player->format = GetFormat(player->channels, player->type, palIsBufferFormatSupportedSOFT);
|
||||
player->format = GetFormat(player->channels, player->type, alIsBufferFormatSupportedSOFT);
|
||||
if(player->format == 0)
|
||||
{
|
||||
fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
|
||||
@@ -203,9 +203,9 @@ static int StartPlayer(StreamPlayer *player)
|
||||
got = readAVAudioData(player->stream, player->data, player->datasize);
|
||||
if(got == 0) break;
|
||||
|
||||
palBufferSamplesSOFT(player->buffers[i], player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
alBufferSamplesSOFT(player->buffers[i], player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
}
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
{
|
||||
@@ -252,9 +252,9 @@ static int UpdatePlayer(StreamPlayer *player)
|
||||
got = readAVAudioData(player->stream, player->data, player->datasize);
|
||||
if(got > 0)
|
||||
{
|
||||
palBufferSamplesSOFT(bufid, player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
alBufferSamplesSOFT(bufid, player->rate, player->format,
|
||||
BytesToFrames(got, player->channels, player->type),
|
||||
player->channels, player->type, player->data);
|
||||
alSourceQueueBuffers(player->source, 1, &bufid);
|
||||
}
|
||||
if(alGetError() != AL_NO_ERROR)
|
||||
@@ -304,8 +304,8 @@ int main(int argc, char **argv)
|
||||
if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
|
||||
{
|
||||
printf("AL_SOFT_buffer_samples supported!\n");
|
||||
palBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT");
|
||||
palIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT");
|
||||
alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT");
|
||||
alIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT");
|
||||
}
|
||||
else
|
||||
printf("AL_SOFT_buffer_samples not supported\n");
|
||||
@@ -318,9 +318,10 @@ int main(int argc, char **argv)
|
||||
if(!OpenPlayerFile(player, argv[i]))
|
||||
continue;
|
||||
|
||||
fprintf(stderr, "Playing %s (%s, %s, %dhz)\n", argv[i],
|
||||
TypeName(player->type), ChannelsName(player->channels),
|
||||
player->rate);
|
||||
printf("Playing %s (%s, %s, %dhz)\n", argv[i],
|
||||
TypeName(player->type), ChannelsName(player->channels),
|
||||
player->rate);
|
||||
fflush(stdout);
|
||||
|
||||
if(!StartPlayer(player))
|
||||
{
|
||||
@@ -334,7 +335,7 @@ int main(int argc, char **argv)
|
||||
/* All done with this file. Close it and go to the next */
|
||||
ClosePlayerFile(player);
|
||||
}
|
||||
fprintf(stderr, "Done.\n");
|
||||
printf("Done.\n");
|
||||
|
||||
/* All files done. Delete the player, and close OpenAL */
|
||||
DeletePlayer(player);
|
||||
|
||||
@@ -98,20 +98,20 @@ static int64_t MemData_seek(void *opaque, int64_t offset, int whence)
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
if(offset < 0 || offset > membuf->length)
|
||||
if(offset < 0 || (uint64_t)offset > membuf->length)
|
||||
return -1;
|
||||
membuf->pos = offset;
|
||||
break;
|
||||
|
||||
case SEEK_CUR:
|
||||
if((offset >= 0 && offset > membuf->length-membuf->pos) ||
|
||||
(offset < 0 && offset < -membuf->pos))
|
||||
if((offset >= 0 && (uint64_t)offset > membuf->length-membuf->pos) ||
|
||||
(offset < 0 && (uint64_t)(-offset) > membuf->pos))
|
||||
return -1;
|
||||
membuf->pos += offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if(offset > 0 || offset < -membuf->length)
|
||||
if(offset > 0 || (uint64_t)(-offset) > membuf->length)
|
||||
return -1;
|
||||
membuf->pos = membuf->length + offset;
|
||||
break;
|
||||
@@ -138,8 +138,10 @@ struct MyStream {
|
||||
|
||||
struct PacketList *Packets;
|
||||
|
||||
char *DecodedData;
|
||||
size_t DecodedDataSize;
|
||||
AVFrame *Frame;
|
||||
|
||||
const uint8_t *FrameData;
|
||||
size_t FrameDataSize;
|
||||
|
||||
FilePtr parent;
|
||||
};
|
||||
@@ -173,7 +175,7 @@ FilePtr openAVFile(const char *fname)
|
||||
* all formats will have it in stream headers */
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
av_close_input_file(file->FmtCtx);
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
|
||||
free(file);
|
||||
@@ -205,8 +207,7 @@ FilePtr openAVData(const char *name, char *buffer, size_t buffer_len)
|
||||
{
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
av_close_input_file(file->FmtCtx);
|
||||
file->FmtCtx = NULL;
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
if(file->FmtCtx)
|
||||
avformat_free_context(file->FmtCtx);
|
||||
@@ -240,8 +241,7 @@ FilePtr openAVCustom(const char *name, void *user_data,
|
||||
{
|
||||
if(avformat_find_stream_info(file->FmtCtx, NULL) >= 0)
|
||||
return file;
|
||||
av_close_input_file(file->FmtCtx);
|
||||
file->FmtCtx = NULL;
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
}
|
||||
if(file->FmtCtx)
|
||||
avformat_free_context(file->FmtCtx);
|
||||
@@ -253,6 +253,21 @@ FilePtr openAVCustom(const char *name, void *user_data,
|
||||
}
|
||||
|
||||
|
||||
void clearAVAudioData(StreamPtr stream)
|
||||
{
|
||||
while(stream->Packets)
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
av_free_packet(&self->pkt);
|
||||
av_free(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void closeAVFile(FilePtr file)
|
||||
{
|
||||
size_t i;
|
||||
@@ -275,12 +290,12 @@ void closeAVFile(FilePtr file)
|
||||
}
|
||||
|
||||
avcodec_close(stream->CodecCtx);
|
||||
av_free(stream->DecodedData);
|
||||
av_free(stream->Frame);
|
||||
free(stream);
|
||||
}
|
||||
free(file->Streams);
|
||||
|
||||
av_close_input_file(file->FmtCtx);
|
||||
avformat_close_input(&file->FmtCtx);
|
||||
free(file);
|
||||
}
|
||||
|
||||
@@ -335,7 +350,7 @@ StreamPtr getAVAudioStream(FilePtr file, int streamnum)
|
||||
|
||||
/* Try to find the codec for the given codec ID, and open it */
|
||||
codec = avcodec_find_decoder(stream->CodecCtx->codec_id);
|
||||
if(!codec || avcodec_open(stream->CodecCtx, codec) < 0)
|
||||
if(!codec || avcodec_open2(stream->CodecCtx, codec, NULL) < 0)
|
||||
{
|
||||
free(stream);
|
||||
return NULL;
|
||||
@@ -343,13 +358,15 @@ StreamPtr getAVAudioStream(FilePtr file, int streamnum)
|
||||
|
||||
/* Allocate space for the decoded data to be stored in before it
|
||||
* gets passed to the app */
|
||||
stream->DecodedData = (char*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
|
||||
if(!stream->DecodedData)
|
||||
stream->Frame = avcodec_alloc_frame();
|
||||
if(!stream->Frame)
|
||||
{
|
||||
avcodec_close(stream->CodecCtx);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->FrameData = NULL;
|
||||
stream->FrameDataSize = 0;
|
||||
|
||||
/* Append the new stream object to the stream list. The original
|
||||
* pointer will remain valid if realloc fails, so we need to use
|
||||
@@ -359,7 +376,7 @@ StreamPtr getAVAudioStream(FilePtr file, int streamnum)
|
||||
if(!temp)
|
||||
{
|
||||
avcodec_close(stream->CodecCtx);
|
||||
av_free(stream->DecodedData);
|
||||
av_free(stream->Frame);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
@@ -483,9 +500,9 @@ next_packet:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *getAVAudioData(StreamPtr stream, size_t *length)
|
||||
uint8_t *getAVAudioData(StreamPtr stream, size_t *length)
|
||||
{
|
||||
int size;
|
||||
int got_frame;
|
||||
int len;
|
||||
|
||||
if(length) *length = 0;
|
||||
@@ -493,25 +510,18 @@ void *getAVAudioData(StreamPtr stream, size_t *length)
|
||||
if(!stream || stream->CodecCtx->codec_type != AVMEDIA_TYPE_AUDIO)
|
||||
return NULL;
|
||||
|
||||
stream->DecodedDataSize = 0;
|
||||
|
||||
next_packet:
|
||||
if(!stream->Packets && !getNextPacket(stream->parent, stream->StreamIdx))
|
||||
return NULL;
|
||||
|
||||
/* Decode some data, and check for errors */
|
||||
size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
while((len=avcodec_decode_audio3(stream->CodecCtx,
|
||||
(int16_t*)stream->DecodedData, &size,
|
||||
&stream->Packets->pkt)) == 0)
|
||||
avcodec_get_frame_defaults(stream->Frame);
|
||||
while((len=avcodec_decode_audio4(stream->CodecCtx, stream->Frame,
|
||||
&got_frame, &stream->Packets->pkt)) < 0)
|
||||
{
|
||||
struct PacketList *self;
|
||||
|
||||
if(size > 0)
|
||||
break;
|
||||
|
||||
/* Packet went unread and no data was given? Drop it and try the next,
|
||||
* I guess... */
|
||||
/* Error? Drop it and try the next, I guess... */
|
||||
self = stream->Packets;
|
||||
stream->Packets = self->next;
|
||||
|
||||
@@ -520,13 +530,8 @@ next_packet:
|
||||
|
||||
if(!stream->Packets)
|
||||
goto next_packet;
|
||||
|
||||
size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||
}
|
||||
|
||||
if(len < 0)
|
||||
return NULL;
|
||||
|
||||
if(len < stream->Packets->pkt.size)
|
||||
{
|
||||
/* Move the unread data to the front and clear the end bits */
|
||||
@@ -548,14 +553,15 @@ next_packet:
|
||||
av_free(self);
|
||||
}
|
||||
|
||||
if(size == 0)
|
||||
if(!got_frame || stream->Frame->nb_samples == 0)
|
||||
goto next_packet;
|
||||
|
||||
/* Set the output buffer size */
|
||||
stream->DecodedDataSize = size;
|
||||
if(length) *length = stream->DecodedDataSize;
|
||||
*length = av_samples_get_buffer_size(NULL, stream->CodecCtx->channels,
|
||||
stream->Frame->nb_samples,
|
||||
stream->CodecCtx->sample_fmt, 1);
|
||||
|
||||
return stream->DecodedData;
|
||||
return stream->Frame->data[0];
|
||||
}
|
||||
|
||||
size_t readAVAudioData(StreamPtr stream, void *data, size_t length)
|
||||
@@ -568,34 +574,33 @@ size_t readAVAudioData(StreamPtr stream, void *data, size_t length)
|
||||
while(dec < length)
|
||||
{
|
||||
/* If there's no decoded data, find some */
|
||||
if(stream->DecodedDataSize == 0)
|
||||
if(stream->FrameDataSize == 0)
|
||||
{
|
||||
if(getAVAudioData(stream, NULL) == NULL)
|
||||
stream->FrameData = getAVAudioData(stream, &stream->FrameDataSize);
|
||||
if(!stream->FrameData)
|
||||
break;
|
||||
}
|
||||
|
||||
if(stream->DecodedDataSize > 0)
|
||||
if(stream->FrameDataSize > 0)
|
||||
{
|
||||
/* Get the amount of bytes remaining to be written, and clamp to
|
||||
* the amount of decoded data we have */
|
||||
size_t rem = length-dec;
|
||||
if(rem > stream->DecodedDataSize)
|
||||
rem = stream->DecodedDataSize;
|
||||
if(rem > stream->FrameDataSize)
|
||||
rem = stream->FrameDataSize;
|
||||
|
||||
/* Copy the data to the app's buffer and increment */
|
||||
if(data != NULL)
|
||||
{
|
||||
memcpy(data, stream->DecodedData, rem);
|
||||
memcpy(data, stream->FrameData, rem);
|
||||
data = (char*)data + rem;
|
||||
}
|
||||
dec += rem;
|
||||
|
||||
/* If there's any decoded data left, move it to the front of the
|
||||
* buffer for next time */
|
||||
if(rem < stream->DecodedDataSize)
|
||||
memmove(stream->DecodedData, &stream->DecodedData[rem],
|
||||
stream->DecodedDataSize - rem);
|
||||
stream->DecodedDataSize -= rem;
|
||||
stream->FrameData += rem;
|
||||
stream->FrameDataSize -= rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ int getAVAudioInfo(StreamPtr stream, ALuint *rate, ALenum *channels, ALenum *typ
|
||||
* from a previously-decoded packet is dropped. The size (in bytes) of the
|
||||
* returned data buffer is stored in 'length', and the returned pointer is only
|
||||
* valid until the next call to getAVAudioData or readAVAudioData. */
|
||||
void *getAVAudioData(StreamPtr stream, size_t *length);
|
||||
uint8_t *getAVAudioData(StreamPtr stream, size_t *length);
|
||||
|
||||
/* The "meat" function. Decodes audio and writes, at most, length bytes into
|
||||
* the provided data buffer. Will only return less for end-of-stream or error
|
||||
@@ -37,72 +37,59 @@
|
||||
#include "alhelpers.h"
|
||||
|
||||
|
||||
const char *ChannelsName(ALenum chans)
|
||||
/* InitAL opens the default device and sets up a context using default
|
||||
* attributes, making the program ready to call OpenAL functions. */
|
||||
int InitAL(void)
|
||||
{
|
||||
switch(chans)
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
/* Open and initialize a device with default settings */
|
||||
device = alcOpenDevice(NULL);
|
||||
if(!device)
|
||||
{
|
||||
case AL_MONO_SOFT: return "Mono";
|
||||
case AL_STEREO_SOFT: return "Stereo";
|
||||
case AL_REAR_SOFT: return "Rear";
|
||||
case AL_QUAD_SOFT: return "Quadraphonic";
|
||||
case AL_5POINT1_SOFT: return "5.1 Surround";
|
||||
case AL_6POINT1_SOFT: return "6.1 Surround";
|
||||
case AL_7POINT1_SOFT: return "7.1 Surround";
|
||||
fprintf(stderr, "Could not open a device!\n");
|
||||
return 1;
|
||||
}
|
||||
return "Unknown Channels";
|
||||
|
||||
ctx = alcCreateContext(device, NULL);
|
||||
if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
|
||||
{
|
||||
if(ctx != NULL)
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
fprintf(stderr, "Could not set a context!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *TypeName(ALenum type)
|
||||
/* CloseAL closes the device belonging to the current context, and destroys the
|
||||
* context. */
|
||||
void CloseAL(void)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: return "S8";
|
||||
case AL_UNSIGNED_BYTE_SOFT: return "U8";
|
||||
case AL_SHORT_SOFT: return "S16";
|
||||
case AL_UNSIGNED_SHORT_SOFT: return "U16";
|
||||
case AL_INT_SOFT: return "S32";
|
||||
case AL_UNSIGNED_INT_SOFT: return "U32";
|
||||
case AL_FLOAT_SOFT: return "Float32";
|
||||
case AL_DOUBLE_SOFT: return "Float64";
|
||||
}
|
||||
return "Unknown Type";
|
||||
}
|
||||
|
||||
|
||||
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
switch(channels)
|
||||
{
|
||||
case AL_MONO_SOFT: size *= 1; break;
|
||||
case AL_STEREO_SOFT: size *= 2; break;
|
||||
case AL_REAR_SOFT: size *= 2; break;
|
||||
case AL_QUAD_SOFT: size *= 4; break;
|
||||
case AL_5POINT1_SOFT: size *= 6; break;
|
||||
case AL_6POINT1_SOFT: size *= 7; break;
|
||||
case AL_7POINT1_SOFT: size *= 8; break;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: size *= sizeof(ALbyte); break;
|
||||
case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break;
|
||||
case AL_SHORT_SOFT: size *= sizeof(ALshort); break;
|
||||
case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break;
|
||||
case AL_INT_SOFT: size *= sizeof(ALint); break;
|
||||
case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break;
|
||||
case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break;
|
||||
case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
return size / FramesToBytes(1, channels, type);
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
ctx = alcGetCurrentContext();
|
||||
if(ctx == NULL)
|
||||
return;
|
||||
|
||||
device = alcGetContextsDevice(ctx);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
}
|
||||
|
||||
|
||||
/* GetFormat retrieves a compatible buffer format given the channel config and
|
||||
* sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
|
||||
* provided, it will be called to find the closest-matching format from
|
||||
* AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
|
||||
* found. */
|
||||
ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT)
|
||||
{
|
||||
ALenum format = AL_NONE;
|
||||
@@ -274,46 +261,67 @@ void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
|
||||
}
|
||||
|
||||
|
||||
int InitAL(void)
|
||||
const char *ChannelsName(ALenum chans)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
/* Open and initialize a device with default settings */
|
||||
device = alcOpenDevice(NULL);
|
||||
if(!device)
|
||||
switch(chans)
|
||||
{
|
||||
fprintf(stderr, "Could not open a device!\n");
|
||||
return 1;
|
||||
case AL_MONO_SOFT: return "Mono";
|
||||
case AL_STEREO_SOFT: return "Stereo";
|
||||
case AL_REAR_SOFT: return "Rear";
|
||||
case AL_QUAD_SOFT: return "Quadraphonic";
|
||||
case AL_5POINT1_SOFT: return "5.1 Surround";
|
||||
case AL_6POINT1_SOFT: return "6.1 Surround";
|
||||
case AL_7POINT1_SOFT: return "7.1 Surround";
|
||||
}
|
||||
|
||||
ctx = alcCreateContext(device, NULL);
|
||||
if(ctx == NULL || alcMakeContextCurrent(ctx) == ALC_FALSE)
|
||||
{
|
||||
if(ctx != NULL)
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
fprintf(stderr, "Could not set a context!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return "Unknown Channels";
|
||||
}
|
||||
|
||||
void CloseAL(void)
|
||||
const char *TypeName(ALenum type)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *ctx;
|
||||
|
||||
/* Close the device belonging to the current context, and destroy the
|
||||
* context. */
|
||||
ctx = alcGetCurrentContext();
|
||||
if(ctx == NULL)
|
||||
return;
|
||||
|
||||
device = alcGetContextsDevice(ctx);
|
||||
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(ctx);
|
||||
alcCloseDevice(device);
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: return "S8";
|
||||
case AL_UNSIGNED_BYTE_SOFT: return "U8";
|
||||
case AL_SHORT_SOFT: return "S16";
|
||||
case AL_UNSIGNED_SHORT_SOFT: return "U16";
|
||||
case AL_INT_SOFT: return "S32";
|
||||
case AL_UNSIGNED_INT_SOFT: return "U32";
|
||||
case AL_FLOAT_SOFT: return "Float32";
|
||||
case AL_DOUBLE_SOFT: return "Float64";
|
||||
}
|
||||
return "Unknown Type";
|
||||
}
|
||||
|
||||
|
||||
ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
switch(channels)
|
||||
{
|
||||
case AL_MONO_SOFT: size *= 1; break;
|
||||
case AL_STEREO_SOFT: size *= 2; break;
|
||||
case AL_REAR_SOFT: size *= 2; break;
|
||||
case AL_QUAD_SOFT: size *= 4; break;
|
||||
case AL_5POINT1_SOFT: size *= 6; break;
|
||||
case AL_6POINT1_SOFT: size *= 7; break;
|
||||
case AL_7POINT1_SOFT: size *= 8; break;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case AL_BYTE_SOFT: size *= sizeof(ALbyte); break;
|
||||
case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break;
|
||||
case AL_SHORT_SOFT: size *= sizeof(ALshort); break;
|
||||
case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break;
|
||||
case AL_INT_SOFT: size *= sizeof(ALint); break;
|
||||
case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break;
|
||||
case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break;
|
||||
case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
|
||||
{
|
||||
return size / FramesToBytes(1, channels, type);
|
||||
}
|
||||
@@ -12,9 +12,9 @@ placement of sounds, making it seem as though they are coming from all around,
|
||||
including above and below the listener, instead of just to the front, back, and
|
||||
sides.
|
||||
|
||||
The built-in data set is based on the KEMAR HRTF diffuse data provided by MIT,
|
||||
which can be found at <http://sound.media.mit.edu/resources/KEMAR.html>. It's
|
||||
only available when using 44100hz playback.
|
||||
The built-in data set is based on the KEMAR HRTF data provided by MIT, which
|
||||
can be found at <http://sound.media.mit.edu/resources/KEMAR.html>. It's only
|
||||
available when using 44100hz playback.
|
||||
|
||||
|
||||
External HRTF Data Sets
|
||||
@@ -26,68 +26,49 @@ own data sets, which could be better suited for their heads, or to work with
|
||||
stereo speakers instead of headphones, or to support more playback sample
|
||||
rates, for example.
|
||||
|
||||
The file format for the data sets is specified below. It uses little-endian
|
||||
byte order. Certain data fields are restricted to specific values (these
|
||||
restriction may be lifted in future versions of the lib).
|
||||
The file format is specified below. It uses little-endian byte order.
|
||||
|
||||
==
|
||||
ALchar magic[8] = "MinPHR00";
|
||||
ALchar magic[8] = "MinPHR01";
|
||||
ALuint sampleRate;
|
||||
|
||||
ALushort hrirCount; /* Required value: 828 */
|
||||
ALushort hrirSize; /* Required value: 32 */
|
||||
ALubyte evCount; /* Required value: 19 */
|
||||
ALubyte hrirSize; /* Can be 8 to 128 in steps of 8. */
|
||||
ALubyte evCount; /* Can be 5 to 128. */
|
||||
|
||||
ALushort evOffset[evCount]; /* Required values:
|
||||
{ 0, 1, 13, 37, 73, 118, 174, 234, 306, 378, 450, 522, 594, 654, 710, 755,
|
||||
791, 815, 827 } */
|
||||
ALubyte azCount[evCount]; /* Each can be 1 to 128. */
|
||||
|
||||
/* NOTE: hrirCount is the sum of all azCounts */
|
||||
ALshort coefficients[hrirCount][hrirSize];
|
||||
ALubyte delays[hrirCount]; /* Element values must not exceed 127 */
|
||||
ALubyte delays[hrirCount]; /* Each can be 0 to 63. */
|
||||
==
|
||||
|
||||
The data is described as thus:
|
||||
|
||||
The file first starts with the 8-byte marker, "MinPHR00", to identify it as an
|
||||
The file first starts with the 8-byte marker, "MinPHR01", to identify it as an
|
||||
HRTF data set. This is followed by an unsigned 32-bit integer, specifying the
|
||||
sample rate the data set is designed for (OpenAL Soft will not use it if the
|
||||
output device's playback rate doesn't match).
|
||||
|
||||
Afterward, an unsigned 16-bit integer specifies the total number of HRIR sets
|
||||
(each HRIR set is a collection of impulse responses forming the coefficients
|
||||
for a convolution filter). The next unsigned 16-bit integer specifies how many
|
||||
samples are in each HRIR set (the number of coefficients in the filter). The
|
||||
following unsigned 8-bit integer specifies the number of elevations used by the
|
||||
data set. The elevations start at the bottom, and increment upwards.
|
||||
Afterward, an unsigned 8-bit integer specifies how many sample points (or
|
||||
finite impulse response filter coefficients) make up each HRIR.
|
||||
|
||||
Following this is an array of unsigned 16-bit integers, one for each elevation
|
||||
which specifies the index offset to the start of the HRIR sets for each given
|
||||
elevation (the number of HRIR sets at each elevation is infered by the offset
|
||||
to the next elevation, or by the total count for the last elevation).
|
||||
The following unsigned 8-bit integer specifies the number of elevations used
|
||||
by the data set. The elevations start at the bottom (-90 degrees), and
|
||||
increment upwards. Following this is an array of unsigned 8-bit integers, one
|
||||
for each elevation which specifies the number of azimuths (and thus HRIRs) that
|
||||
make up each elevation. Azimuths start clockwise from the front, constructing
|
||||
a full circle for the left ear only. The right ear uses the same HRIRs but in
|
||||
reverse (ie, left = angle, right = 360-angle).
|
||||
|
||||
The actual coefficients follow. Each coefficient is a signed 16-bit sample,
|
||||
with each HRIR set being a consecutive number of samples. For each elevation,
|
||||
the HRIR sets first start with a neutral "in-front" set (that is, one that is
|
||||
applied equally to the left and right outputs). After this, the sets follow a
|
||||
clockwise pattern, constructing a full circle for the left ear only. The right
|
||||
ear uses the same sets but in reverse (ie, left = angle, right = 360-angle).
|
||||
|
||||
After the coefficients is an array of unsigned 8-bit delay values, one for each
|
||||
HRIR set. This is the delay, in samples, after recieving an input sample before
|
||||
before it's added in to the convolution filter that the corresponding HRIR set
|
||||
operates on and gets heard.
|
||||
|
||||
|
||||
Note that the HRTF data is expected to be minimum-phase reconstructed. The
|
||||
time delays are handled by OpenAL Soft according to the specified delay[]
|
||||
values, and afterward the samples are fed into the convolution filter using the
|
||||
corresponding coefficients. This allows for less processing by using a shorter
|
||||
convolution filter, as it skips the first coefficients that do little more than
|
||||
cause a timed delay, as well as the tailing coefficients that are used to
|
||||
equalize the length of all the sets and contribute nothing.
|
||||
|
||||
For reference, the built-in data set uses a 32-sample convolution filter while
|
||||
with each HRIR being a consecutive number of sample points. The HRIRs must be
|
||||
minimum-phase. This allows the use of a smaller filter length, reducing
|
||||
computation. For reference, the built-in data set uses a 32-point filter while
|
||||
even the smallest data set provided by MIT used a 128-sample filter (a 4x
|
||||
reduction by applying minimum-phase reconstruction). Theoretically, one could
|
||||
further reduce the minimum-phase version down to a 16-sample convolution filter
|
||||
with little quality loss.
|
||||
further reduce the minimum-phase version down to a 16-point filter with only a
|
||||
small reduction in quality.
|
||||
|
||||
After the coefficients is an array of unsigned 8-bit delay values, one for
|
||||
each HRIR. This is the propagation delay (in samples) a signal must wait before
|
||||
being convolved with the corresponding minimum-phase HRIR filter.
|
||||
|
||||
+510
-572
File diff suppressed because it is too large
Load Diff
+101
-144
@@ -21,25 +21,20 @@ extern "C" {
|
||||
#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
|
||||
/** Deprecated macro. */
|
||||
#define ALCAPI ALC_API
|
||||
#define ALCAPIENTRY ALC_APIENTRY
|
||||
#define ALC_INVALID 0
|
||||
|
||||
/** Supported ALC version? */
|
||||
#define ALC_VERSION_0_1 1
|
||||
|
||||
#define ALC_VERSION_0_1 1
|
||||
|
||||
/** Opaque device handle */
|
||||
typedef struct ALCdevice_struct ALCdevice;
|
||||
/** Opaque context handle */
|
||||
typedef struct ALCcontext_struct ALCcontext;
|
||||
|
||||
|
||||
/** 8-bit boolean */
|
||||
typedef char ALCboolean;
|
||||
|
||||
@@ -82,196 +77,158 @@ typedef void ALCvoid;
|
||||
|
||||
/* Enumerant values begin at column 50. No tabs. */
|
||||
|
||||
/* Boolean False. */
|
||||
/** Boolean False. */
|
||||
#define ALC_FALSE 0
|
||||
|
||||
/* Boolean True. */
|
||||
/** Boolean True. */
|
||||
#define ALC_TRUE 1
|
||||
|
||||
/**
|
||||
* followed by <int> Hz
|
||||
*/
|
||||
/** Context attribute: <int> Hz. */
|
||||
#define ALC_FREQUENCY 0x1007
|
||||
|
||||
/**
|
||||
* followed by <int> Hz
|
||||
*/
|
||||
/** Context attribute: <int> Hz. */
|
||||
#define ALC_REFRESH 0x1008
|
||||
|
||||
/**
|
||||
* followed by AL_TRUE, AL_FALSE
|
||||
*/
|
||||
/** Context attribute: AL_TRUE or AL_FALSE. */
|
||||
#define ALC_SYNC 0x1009
|
||||
|
||||
/**
|
||||
* followed by <int> Num of requested Mono (3D) Sources
|
||||
*/
|
||||
/** Context attribute: <int> requested Mono (3D) Sources. */
|
||||
#define ALC_MONO_SOURCES 0x1010
|
||||
|
||||
/**
|
||||
* followed by <int> Num of requested Stereo Sources
|
||||
*/
|
||||
/** Context attribute: <int> requested Stereo Sources. */
|
||||
#define ALC_STEREO_SOURCES 0x1011
|
||||
|
||||
/**
|
||||
* errors
|
||||
*/
|
||||
|
||||
/**
|
||||
* No error
|
||||
*/
|
||||
/** No error. */
|
||||
#define ALC_NO_ERROR 0
|
||||
|
||||
/**
|
||||
* No device
|
||||
*/
|
||||
/** Invalid device handle. */
|
||||
#define ALC_INVALID_DEVICE 0xA001
|
||||
|
||||
/**
|
||||
* invalid context ID
|
||||
*/
|
||||
/** Invalid context handle. */
|
||||
#define ALC_INVALID_CONTEXT 0xA002
|
||||
|
||||
/**
|
||||
* bad enum
|
||||
*/
|
||||
/** Invalid enum parameter passed to an ALC call. */
|
||||
#define ALC_INVALID_ENUM 0xA003
|
||||
|
||||
/**
|
||||
* bad value
|
||||
*/
|
||||
/** Invalid value parameter passed to an ALC call. */
|
||||
#define ALC_INVALID_VALUE 0xA004
|
||||
|
||||
/**
|
||||
* Out of memory.
|
||||
*/
|
||||
/** 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
|
||||
|
||||
/** Runtime ALC version. */
|
||||
#define ALC_MAJOR_VERSION 0x1000
|
||||
#define ALC_MINOR_VERSION 0x1001
|
||||
|
||||
/** Context attribute list properties. */
|
||||
#define ALC_ATTRIBUTES_SIZE 0x1002
|
||||
#define ALC_ALL_ATTRIBUTES 0x1003
|
||||
|
||||
|
||||
/** String for the default device specifier. */
|
||||
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||
/**
|
||||
* Capture extension
|
||||
* String for the given device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known device specifiers (list ends with an empty string).
|
||||
*/
|
||||
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||
/** String for space-separated list of ALC extensions. */
|
||||
#define ALC_EXTENSIONS 0x1006
|
||||
|
||||
|
||||
/** Capture extension */
|
||||
#define ALC_EXT_CAPTURE 1
|
||||
/**
|
||||
* String for the given capture device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known capture device specifiers (list ends with an empty string).
|
||||
*/
|
||||
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
|
||||
/** String for the default capture device specifier. */
|
||||
#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
|
||||
/** Number of sample frames available for capture. */
|
||||
#define ALC_CAPTURE_SAMPLES 0x312
|
||||
|
||||
|
||||
/**
|
||||
* ALC_ENUMERATE_ALL_EXT enums
|
||||
*/
|
||||
/** Enumerate All extension */
|
||||
#define ALC_ENUMERATE_ALL_EXT 1
|
||||
/** String for the default extended device specifier. */
|
||||
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||
/**
|
||||
* String for the given extended device's specifier.
|
||||
*
|
||||
* If device handle is NULL, it is instead a null-char separated list of
|
||||
* strings of known extended device specifiers (list ends with an empty string).
|
||||
*/
|
||||
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
|
||||
|
||||
/*
|
||||
* Context Management
|
||||
*/
|
||||
ALC_API ALCcontext * ALC_APIENTRY alcCreateContext( ALCdevice *device, const ALCint* attrlist );
|
||||
/** 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);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* Obtain the most recent Device error.
|
||||
*/
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetError( ALCdevice *device );
|
||||
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 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);
|
||||
|
||||
ALC_API void * ALC_APIENTRY alcGetProcAddress( ALCdevice *device, const ALCchar *funcname );
|
||||
/** Query function. */
|
||||
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param);
|
||||
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
|
||||
|
||||
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue( ALCdevice *device, const ALCchar *enumname );
|
||||
/** Capture function. */
|
||||
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);
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
/** Pointer-to-function type, 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 *values);
|
||||
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(__cplusplus)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,21 @@
|
||||
#define AL_ALEXT_H
|
||||
|
||||
#include <stddef.h>
|
||||
/* Define int64_t and uint64_t types */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
#include <inttypes.h>
|
||||
#elif defined(_WIN32) && defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
#elif defined(_WIN32)
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#else
|
||||
/* Fallback if nothing above works */
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include "alc.h"
|
||||
#include "al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -289,6 +304,50 @@ ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffe
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_STEREO_ANGLES
|
||||
#define AL_EXT_STEREO_ANGLES 1
|
||||
#define AL_STEREO_ANGLES 0x1030
|
||||
#endif
|
||||
|
||||
#ifndef AL_EXT_SOURCE_RADIUS
|
||||
#define AL_EXT_SOURCE_RADIUS 1
|
||||
#define AL_SOURCE_RADIUS 0x1031
|
||||
#endif
|
||||
|
||||
#ifndef AL_SOFT_source_latency
|
||||
#define AL_SOFT_source_latency 1
|
||||
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
|
||||
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
|
||||
typedef int64_t ALint64SOFT;
|
||||
typedef uint64_t ALuint64SOFT;
|
||||
typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble);
|
||||
typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT);
|
||||
typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT);
|
||||
typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*);
|
||||
typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*);
|
||||
#ifdef AL_ALEXT_PROTOTYPES
|
||||
AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value);
|
||||
AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3);
|
||||
AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values);
|
||||
AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value);
|
||||
AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3);
|
||||
AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values);
|
||||
AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value);
|
||||
AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3);
|
||||
AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values);
|
||||
AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value);
|
||||
AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3);
|
||||
AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#define AL_EFX_H
|
||||
|
||||
|
||||
#include "alc.h"
|
||||
#include "al.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -8,4 +8,4 @@ Description: OpenAL is a cross-platform 3D audio API
|
||||
Requires: @PKG_CONFIG_REQUIRES@
|
||||
Version: @PACKAGE_VERSION@
|
||||
Libs: -L${libdir} -l@LIBNAME@ @PKG_CONFIG_LIBS@
|
||||
Cflags: -I${includedir} @PKG_CONFIG_CFLAGS@
|
||||
Cflags: -I${includedir} -I${includedir}/AL @PKG_CONFIG_CFLAGS@
|
||||
|
||||
+2010
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,421 @@
|
||||
# This is a makehrtf HRIR definition file. It is used to define the layout
|
||||
# and source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform an average of the left and right ear
|
||||
# HRIRs from any raw dataset from the IRCAM/AKG Listen HRTF database.
|
||||
#
|
||||
# The datasets are available free of charge from:
|
||||
#
|
||||
# http://recherche.ircam.fr/equipes/salles/listen/index.html
|
||||
#
|
||||
# Contact for the Listen HRTF Database:
|
||||
#
|
||||
# Olivier Warusfel <olivier.warusfel@ircam.fr>,
|
||||
# Room Acoustics Team, IRCAM
|
||||
# 1, place Igor Stravinsky
|
||||
# 75004 PARIS, France
|
||||
|
||||
rate = 44100
|
||||
|
||||
# The raw sets have up to 8192 samples, but 2048 seems large enough.
|
||||
points = 2048
|
||||
|
||||
# The IRCAM sets are not as dense as the MIT set.
|
||||
azimuths = 1, 6, 12, 24, 24, 24, 24, 24, 24, 24, 12, 6, 1
|
||||
|
||||
# No head radius was provided. Just use the average radius of 9 cm.
|
||||
radius = 0.09
|
||||
|
||||
# The distance between the source and the listener (in meters).
|
||||
distance = 1.95
|
||||
|
||||
# The IRCAM source azimuth is counter-clockwise, so it needs to be flipped.
|
||||
# Left and right ear HRIRs (from the respective WAVE channels) are averaged.
|
||||
|
||||
# Repalce all occurrences of IRC_#### for the desired subject (1005 was used
|
||||
# in this demonstration).
|
||||
|
||||
[ 3, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P315.wav"
|
||||
[ 3, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav"
|
||||
[ 3, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav"
|
||||
[ 3, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav"
|
||||
[ 3, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav"
|
||||
[ 3, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav"
|
||||
[ 3, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav"
|
||||
[ 3, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav"
|
||||
[ 3, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav"
|
||||
[ 3, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav"
|
||||
[ 3, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav"
|
||||
[ 3, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav"
|
||||
[ 3, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P315.wav"
|
||||
[ 3, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P315.wav"
|
||||
[ 3, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P315.wav"
|
||||
[ 3, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P315.wav"
|
||||
[ 3, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P315.wav"
|
||||
[ 3, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P315.wav"
|
||||
[ 3, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P315.wav"
|
||||
[ 3, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P315.wav"
|
||||
[ 3, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P315.wav"
|
||||
[ 3, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P315.wav"
|
||||
[ 3, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P315.wav"
|
||||
[ 3, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P315.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P315.wav"
|
||||
|
||||
[ 4, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P330.wav"
|
||||
[ 4, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav"
|
||||
[ 4, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav"
|
||||
[ 4, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav"
|
||||
[ 4, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav"
|
||||
[ 4, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav"
|
||||
[ 4, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav"
|
||||
[ 4, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav"
|
||||
[ 4, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav"
|
||||
[ 4, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav"
|
||||
[ 4, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav"
|
||||
[ 4, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav"
|
||||
[ 4, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P330.wav"
|
||||
[ 4, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P330.wav"
|
||||
[ 4, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P330.wav"
|
||||
[ 4, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P330.wav"
|
||||
[ 4, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P330.wav"
|
||||
[ 4, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P330.wav"
|
||||
[ 4, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P330.wav"
|
||||
[ 4, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P330.wav"
|
||||
[ 4, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P330.wav"
|
||||
[ 4, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P330.wav"
|
||||
[ 4, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P330.wav"
|
||||
[ 4, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P330.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P330.wav"
|
||||
|
||||
[ 5, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P345.wav"
|
||||
[ 5, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav"
|
||||
[ 5, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav"
|
||||
[ 5, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav"
|
||||
[ 5, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav"
|
||||
[ 5, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav"
|
||||
[ 5, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav"
|
||||
[ 5, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav"
|
||||
[ 5, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav"
|
||||
[ 5, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav"
|
||||
[ 5, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav"
|
||||
[ 5, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav"
|
||||
[ 5, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P345.wav"
|
||||
[ 5, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P345.wav"
|
||||
[ 5, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P345.wav"
|
||||
[ 5, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P345.wav"
|
||||
[ 5, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P345.wav"
|
||||
[ 5, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P345.wav"
|
||||
[ 5, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P345.wav"
|
||||
[ 5, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P345.wav"
|
||||
[ 5, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P345.wav"
|
||||
[ 5, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P345.wav"
|
||||
[ 5, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P345.wav"
|
||||
[ 5, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P345.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P345.wav"
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P000.wav"
|
||||
[ 6, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav"
|
||||
[ 6, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav"
|
||||
[ 6, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav"
|
||||
[ 6, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav"
|
||||
[ 6, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav"
|
||||
[ 6, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav"
|
||||
[ 6, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav"
|
||||
[ 6, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav"
|
||||
[ 6, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav"
|
||||
[ 6, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav"
|
||||
[ 6, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav"
|
||||
[ 6, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P000.wav"
|
||||
[ 6, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P000.wav"
|
||||
[ 6, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P000.wav"
|
||||
[ 6, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P000.wav"
|
||||
[ 6, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P000.wav"
|
||||
[ 6, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P000.wav"
|
||||
[ 6, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P000.wav"
|
||||
[ 6, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P000.wav"
|
||||
[ 6, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P000.wav"
|
||||
[ 6, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P000.wav"
|
||||
[ 6, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P000.wav"
|
||||
[ 6, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P000.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P000.wav"
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P015.wav"
|
||||
[ 7, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav"
|
||||
[ 7, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav"
|
||||
[ 7, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav"
|
||||
[ 7, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav"
|
||||
[ 7, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav"
|
||||
[ 7, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav"
|
||||
[ 7, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav"
|
||||
[ 7, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav"
|
||||
[ 7, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav"
|
||||
[ 7, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav"
|
||||
[ 7, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav"
|
||||
[ 7, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P015.wav"
|
||||
[ 7, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P015.wav"
|
||||
[ 7, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P015.wav"
|
||||
[ 7, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P015.wav"
|
||||
[ 7, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P015.wav"
|
||||
[ 7, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P015.wav"
|
||||
[ 7, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P015.wav"
|
||||
[ 7, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P015.wav"
|
||||
[ 7, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P015.wav"
|
||||
[ 7, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P015.wav"
|
||||
[ 7, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P015.wav"
|
||||
[ 7, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P015.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P015.wav"
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P030.wav"
|
||||
[ 8, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav"
|
||||
[ 8, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav"
|
||||
[ 8, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav"
|
||||
[ 8, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav"
|
||||
[ 8, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav"
|
||||
[ 8, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav"
|
||||
[ 8, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav"
|
||||
[ 8, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav"
|
||||
[ 8, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav"
|
||||
[ 8, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav"
|
||||
[ 8, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav"
|
||||
[ 8, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P030.wav"
|
||||
[ 8, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P030.wav"
|
||||
[ 8, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P030.wav"
|
||||
[ 8, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P030.wav"
|
||||
[ 8, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P030.wav"
|
||||
[ 8, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P030.wav"
|
||||
[ 8, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P030.wav"
|
||||
[ 8, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P030.wav"
|
||||
[ 8, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P030.wav"
|
||||
[ 8, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P030.wav"
|
||||
[ 8, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P030.wav"
|
||||
[ 8, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P030.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P030.wav"
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P045.wav"
|
||||
[ 9, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav"
|
||||
[ 9, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav"
|
||||
[ 9, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav"
|
||||
[ 9, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav"
|
||||
[ 9, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav"
|
||||
[ 9, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav"
|
||||
[ 9, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav"
|
||||
[ 9, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav"
|
||||
[ 9, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav"
|
||||
[ 9, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav"
|
||||
[ 9, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav"
|
||||
[ 9, 12 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P045.wav"
|
||||
[ 9, 13 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T165_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T195_P045.wav"
|
||||
[ 9, 14 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P045.wav"
|
||||
[ 9, 15 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T135_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T225_P045.wav"
|
||||
[ 9, 16 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P045.wav"
|
||||
[ 9, 17 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T105_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T255_P045.wav"
|
||||
[ 9, 18 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P045.wav"
|
||||
[ 9, 19 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T075_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T285_P045.wav"
|
||||
[ 9, 20 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P045.wav"
|
||||
[ 9, 21 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T045_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T315_P045.wav"
|
||||
[ 9, 22 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P045.wav"
|
||||
[ 9, 23 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T015_P045.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T345_P045.wav"
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P060.wav"
|
||||
[ 10, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav"
|
||||
[ 10, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav"
|
||||
[ 10, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav"
|
||||
[ 10, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav"
|
||||
[ 10, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav"
|
||||
[ 10, 6 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P060.wav"
|
||||
[ 10, 7 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T150_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T210_P060.wav"
|
||||
[ 10, 8 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P060.wav"
|
||||
[ 10, 9 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T090_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T270_P060.wav"
|
||||
[ 10, 10 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P060.wav"
|
||||
[ 10, 11 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T030_P060.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T330_P060.wav"
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P075.wav"
|
||||
[ 11, 1 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav"
|
||||
[ 11, 2 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav"
|
||||
[ 11, 3 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T180_P075.wav"
|
||||
[ 11, 4 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T120_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T240_P075.wav"
|
||||
[ 11, 5 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T060_P075.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T300_P075.wav"
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav"
|
||||
+ wave (1) : "./IRC/RAW/WAV/IRC_1005_R/IRC_1005_R_R0195_T000_P090.wav"
|
||||
|
||||
@@ -0,0 +1,819 @@
|
||||
# This is a makehrtf HRIR definition file. It is used to define the layout
|
||||
# and source data to be processed into an OpenAL Soft compatible HRTF.
|
||||
#
|
||||
# This definition is used to transform the left ear HRIRs from the full set
|
||||
# of KEMAR HRIRs provided by Bill Gardner <billg@media.mit.edu> and Keith
|
||||
# Martin <kdm@media.mit.edu> of MIT Media Laboratory.
|
||||
#
|
||||
# The data (full.tar.Z or full.zip) is available from:
|
||||
#
|
||||
# http://sound.media.mit.edu/resources/KEMAR.html
|
||||
#
|
||||
# It is copyright 1994 by MIT Media Laboratory, and provided free of charge
|
||||
# with no restrictions on use so long as the authors (above) are cited.
|
||||
#
|
||||
# This definition is used to generate the internal HRTF table used by OpenAL
|
||||
# Soft.
|
||||
|
||||
# The following are the dataset metrics. They must always be specified at
|
||||
# start of a definition file, but their order is not important.
|
||||
|
||||
# Sampling rate of the HRIR data (in hertz).
|
||||
rate = 44100
|
||||
|
||||
# The number of points to use from the HRIR data. This should be a
|
||||
# sufficiently large value (to encompass the entire impulse response). It
|
||||
# cannot be smaller than the truncation size (default is 32) specified on the
|
||||
# command line.
|
||||
points = 512
|
||||
|
||||
# A list of the number of azimuths measured for each elevation. There must
|
||||
# be at least 5 elevations covering the 180 degrees for the dataset to be
|
||||
# viable.
|
||||
azimuths = 1, 12, 24, 36, 45, 56, 60, 72, 72, 72, 72, 72, 60, 56, 45, 36, 24, 12, 1
|
||||
|
||||
# The approximate radius (measured ear-to-ear) of the listener's head (in
|
||||
# meters). This does not have to match the dataset, since makehrtf uses a
|
||||
# spherical model to reconstruct the propagation delay.
|
||||
radius = 0.09
|
||||
|
||||
# The distance between the source and the listener (in meters). This does
|
||||
# have to match the dataset, but it's effect is minimal at the moment due to
|
||||
# the coupled nature of OpenAL Soft's HRTF model.
|
||||
distance = 1.4
|
||||
|
||||
# Following the metrics is the list of source HRIRs for each elevation and
|
||||
# azimuth pair. They don't have to be specified in order, but the final
|
||||
# composition must not be sparse. They can however begin above a number of
|
||||
# elevations (as typical for HRIR measurements).
|
||||
#
|
||||
# The elevation and azimuth indices are used to determine the resulting polar
|
||||
# coordinates following OpenAL Soft's convention (-90 degree elevation
|
||||
# increasing counter-clockwise from the bottom; 0 degree azimuth increasing
|
||||
# clockwise from the front).
|
||||
#
|
||||
# More than one HRIR can be used per source, in which case the average
|
||||
# magnitude response of all references for that source is used.
|
||||
#
|
||||
# Source specification is of the form (~BNF):
|
||||
#
|
||||
# source = '[' ev_index ',' az_index ']' '=' source_ref [ '+' source_ref ]*
|
||||
#
|
||||
# ev_index = unsigned_integer
|
||||
# az_index = unsigned_integer
|
||||
# source_ref = ref_spec ':' filename
|
||||
#
|
||||
# ref_spec = ( wave_fmt '(' wave_parms ')' [ '@' start_sample ] ) |
|
||||
# ( bin_fmt '(' bini_parms ')' [ '@' start_bytes ] ) |
|
||||
# ( bin_fmt '(' binf_parms ')' [ '@' start_bytes ] ) |
|
||||
# ( ascii_fmt '(' asci_parms ')' [ '@' start_elements ] ) |
|
||||
# ( ascii_fmt '(' ascf_parms ')' [ '@' start_elements ] )
|
||||
# filename = double_quoted_string
|
||||
#
|
||||
# wave_fmt = 'wave'
|
||||
# wave_parms = channel
|
||||
# bin_fmt = 'bin_le' | 'bin_be'
|
||||
# bini_parms = 'int' ',' byte_size [ ',' bin_sig_bits ] [ ';' skip_bytes ]
|
||||
# binf_parms = 'fp' ',' byte_size [ ';' skip_bytes ]
|
||||
# ascii_fmt = 'ascii'
|
||||
# asci_parms = 'int' ',' sig_bits [ ';' skip_elements ]
|
||||
# ascf_parms = 'fp' [ ';' skip_elements ]
|
||||
# start_sample = unsigned_integer
|
||||
# start_bytes = unsigned_integer
|
||||
# start_elements = unsigned_integer
|
||||
#
|
||||
# channel = unsigned_integer
|
||||
# byte_size = unsigned_integer
|
||||
# bin_sig_bits = signed_integer
|
||||
# skip_bytes = unsigned_integer
|
||||
# sig_bits = unsigned_integer
|
||||
# skip_elements = unsigned_integer
|
||||
#
|
||||
# For bin_sig_bits, positive values mean the significant bits start at the
|
||||
# MSB (padding toward the LSB) while negative values mean they start at the
|
||||
# LSB.
|
||||
|
||||
[ 5, 0 ] = wave (0) : "./MITfull/elev-40/L-40e000a.wav"
|
||||
[ 5, 1 ] = wave (0) : "./MITfull/elev-40/L-40e006a.wav"
|
||||
[ 5, 2 ] = wave (0) : "./MITfull/elev-40/L-40e013a.wav"
|
||||
[ 5, 3 ] = wave (0) : "./MITfull/elev-40/L-40e019a.wav"
|
||||
[ 5, 4 ] = wave (0) : "./MITfull/elev-40/L-40e026a.wav"
|
||||
[ 5, 5 ] = wave (0) : "./MITfull/elev-40/L-40e032a.wav"
|
||||
[ 5, 6 ] = wave (0) : "./MITfull/elev-40/L-40e039a.wav"
|
||||
[ 5, 7 ] = wave (0) : "./MITfull/elev-40/L-40e045a.wav"
|
||||
[ 5, 8 ] = wave (0) : "./MITfull/elev-40/L-40e051a.wav"
|
||||
[ 5, 9 ] = wave (0) : "./MITfull/elev-40/L-40e058a.wav"
|
||||
[ 5, 10 ] = wave (0) : "./MITfull/elev-40/L-40e064a.wav"
|
||||
[ 5, 11 ] = wave (0) : "./MITfull/elev-40/L-40e071a.wav"
|
||||
[ 5, 12 ] = wave (0) : "./MITfull/elev-40/L-40e077a.wav"
|
||||
[ 5, 13 ] = wave (0) : "./MITfull/elev-40/L-40e084a.wav"
|
||||
[ 5, 14 ] = wave (0) : "./MITfull/elev-40/L-40e090a.wav"
|
||||
[ 5, 15 ] = wave (0) : "./MITfull/elev-40/L-40e096a.wav"
|
||||
[ 5, 16 ] = wave (0) : "./MITfull/elev-40/L-40e103a.wav"
|
||||
[ 5, 17 ] = wave (0) : "./MITfull/elev-40/L-40e109a.wav"
|
||||
[ 5, 18 ] = wave (0) : "./MITfull/elev-40/L-40e116a.wav"
|
||||
[ 5, 19 ] = wave (0) : "./MITfull/elev-40/L-40e122a.wav"
|
||||
[ 5, 20 ] = wave (0) : "./MITfull/elev-40/L-40e129a.wav"
|
||||
[ 5, 21 ] = wave (0) : "./MITfull/elev-40/L-40e135a.wav"
|
||||
[ 5, 22 ] = wave (0) : "./MITfull/elev-40/L-40e141a.wav"
|
||||
[ 5, 23 ] = wave (0) : "./MITfull/elev-40/L-40e148a.wav"
|
||||
[ 5, 24 ] = wave (0) : "./MITfull/elev-40/L-40e154a.wav"
|
||||
[ 5, 25 ] = wave (0) : "./MITfull/elev-40/L-40e161a.wav"
|
||||
[ 5, 26 ] = wave (0) : "./MITfull/elev-40/L-40e167a.wav"
|
||||
[ 5, 27 ] = wave (0) : "./MITfull/elev-40/L-40e174a.wav"
|
||||
[ 5, 28 ] = wave (0) : "./MITfull/elev-40/L-40e180a.wav"
|
||||
[ 5, 29 ] = wave (0) : "./MITfull/elev-40/L-40e186a.wav"
|
||||
[ 5, 30 ] = wave (0) : "./MITfull/elev-40/L-40e193a.wav"
|
||||
[ 5, 31 ] = wave (0) : "./MITfull/elev-40/L-40e199a.wav"
|
||||
[ 5, 32 ] = wave (0) : "./MITfull/elev-40/L-40e206a.wav"
|
||||
[ 5, 33 ] = wave (0) : "./MITfull/elev-40/L-40e212a.wav"
|
||||
[ 5, 34 ] = wave (0) : "./MITfull/elev-40/L-40e219a.wav"
|
||||
[ 5, 35 ] = wave (0) : "./MITfull/elev-40/L-40e225a.wav"
|
||||
[ 5, 36 ] = wave (0) : "./MITfull/elev-40/L-40e231a.wav"
|
||||
[ 5, 37 ] = wave (0) : "./MITfull/elev-40/L-40e238a.wav"
|
||||
[ 5, 38 ] = wave (0) : "./MITfull/elev-40/L-40e244a.wav"
|
||||
[ 5, 39 ] = wave (0) : "./MITfull/elev-40/L-40e251a.wav"
|
||||
[ 5, 40 ] = wave (0) : "./MITfull/elev-40/L-40e257a.wav"
|
||||
[ 5, 41 ] = wave (0) : "./MITfull/elev-40/L-40e264a.wav"
|
||||
[ 5, 42 ] = wave (0) : "./MITfull/elev-40/L-40e270a.wav"
|
||||
[ 5, 43 ] = wave (0) : "./MITfull/elev-40/L-40e276a.wav"
|
||||
[ 5, 44 ] = wave (0) : "./MITfull/elev-40/L-40e283a.wav"
|
||||
[ 5, 45 ] = wave (0) : "./MITfull/elev-40/L-40e289a.wav"
|
||||
[ 5, 46 ] = wave (0) : "./MITfull/elev-40/L-40e296a.wav"
|
||||
[ 5, 47 ] = wave (0) : "./MITfull/elev-40/L-40e302a.wav"
|
||||
[ 5, 48 ] = wave (0) : "./MITfull/elev-40/L-40e309a.wav"
|
||||
[ 5, 49 ] = wave (0) : "./MITfull/elev-40/L-40e315a.wav"
|
||||
[ 5, 50 ] = wave (0) : "./MITfull/elev-40/L-40e321a.wav"
|
||||
[ 5, 51 ] = wave (0) : "./MITfull/elev-40/L-40e328a.wav"
|
||||
[ 5, 52 ] = wave (0) : "./MITfull/elev-40/L-40e334a.wav"
|
||||
[ 5, 53 ] = wave (0) : "./MITfull/elev-40/L-40e341a.wav"
|
||||
[ 5, 54 ] = wave (0) : "./MITfull/elev-40/L-40e347a.wav"
|
||||
[ 5, 55 ] = wave (0) : "./MITfull/elev-40/L-40e354a.wav"
|
||||
|
||||
[ 6, 0 ] = wave (0) : "./MITfull/elev-30/L-30e000a.wav"
|
||||
[ 6, 1 ] = wave (0) : "./MITfull/elev-30/L-30e006a.wav"
|
||||
[ 6, 2 ] = wave (0) : "./MITfull/elev-30/L-30e012a.wav"
|
||||
[ 6, 3 ] = wave (0) : "./MITfull/elev-30/L-30e018a.wav"
|
||||
[ 6, 4 ] = wave (0) : "./MITfull/elev-30/L-30e024a.wav"
|
||||
[ 6, 5 ] = wave (0) : "./MITfull/elev-30/L-30e030a.wav"
|
||||
[ 6, 6 ] = wave (0) : "./MITfull/elev-30/L-30e036a.wav"
|
||||
[ 6, 7 ] = wave (0) : "./MITfull/elev-30/L-30e042a.wav"
|
||||
[ 6, 8 ] = wave (0) : "./MITfull/elev-30/L-30e048a.wav"
|
||||
[ 6, 9 ] = wave (0) : "./MITfull/elev-30/L-30e054a.wav"
|
||||
[ 6, 10 ] = wave (0) : "./MITfull/elev-30/L-30e060a.wav"
|
||||
[ 6, 11 ] = wave (0) : "./MITfull/elev-30/L-30e066a.wav"
|
||||
[ 6, 12 ] = wave (0) : "./MITfull/elev-30/L-30e072a.wav"
|
||||
[ 6, 13 ] = wave (0) : "./MITfull/elev-30/L-30e078a.wav"
|
||||
[ 6, 14 ] = wave (0) : "./MITfull/elev-30/L-30e084a.wav"
|
||||
[ 6, 15 ] = wave (0) : "./MITfull/elev-30/L-30e090a.wav"
|
||||
[ 6, 16 ] = wave (0) : "./MITfull/elev-30/L-30e096a.wav"
|
||||
[ 6, 17 ] = wave (0) : "./MITfull/elev-30/L-30e102a.wav"
|
||||
[ 6, 18 ] = wave (0) : "./MITfull/elev-30/L-30e108a.wav"
|
||||
[ 6, 19 ] = wave (0) : "./MITfull/elev-30/L-30e114a.wav"
|
||||
[ 6, 20 ] = wave (0) : "./MITfull/elev-30/L-30e120a.wav"
|
||||
[ 6, 21 ] = wave (0) : "./MITfull/elev-30/L-30e126a.wav"
|
||||
[ 6, 22 ] = wave (0) : "./MITfull/elev-30/L-30e132a.wav"
|
||||
[ 6, 23 ] = wave (0) : "./MITfull/elev-30/L-30e138a.wav"
|
||||
[ 6, 24 ] = wave (0) : "./MITfull/elev-30/L-30e144a.wav"
|
||||
[ 6, 25 ] = wave (0) : "./MITfull/elev-30/L-30e150a.wav"
|
||||
[ 6, 26 ] = wave (0) : "./MITfull/elev-30/L-30e156a.wav"
|
||||
[ 6, 27 ] = wave (0) : "./MITfull/elev-30/L-30e162a.wav"
|
||||
[ 6, 28 ] = wave (0) : "./MITfull/elev-30/L-30e168a.wav"
|
||||
[ 6, 29 ] = wave (0) : "./MITfull/elev-30/L-30e174a.wav"
|
||||
[ 6, 30 ] = wave (0) : "./MITfull/elev-30/L-30e180a.wav"
|
||||
[ 6, 31 ] = wave (0) : "./MITfull/elev-30/L-30e186a.wav"
|
||||
[ 6, 32 ] = wave (0) : "./MITfull/elev-30/L-30e192a.wav"
|
||||
[ 6, 33 ] = wave (0) : "./MITfull/elev-30/L-30e198a.wav"
|
||||
[ 6, 34 ] = wave (0) : "./MITfull/elev-30/L-30e204a.wav"
|
||||
[ 6, 35 ] = wave (0) : "./MITfull/elev-30/L-30e210a.wav"
|
||||
[ 6, 36 ] = wave (0) : "./MITfull/elev-30/L-30e216a.wav"
|
||||
[ 6, 37 ] = wave (0) : "./MITfull/elev-30/L-30e222a.wav"
|
||||
[ 6, 38 ] = wave (0) : "./MITfull/elev-30/L-30e228a.wav"
|
||||
[ 6, 39 ] = wave (0) : "./MITfull/elev-30/L-30e234a.wav"
|
||||
[ 6, 40 ] = wave (0) : "./MITfull/elev-30/L-30e240a.wav"
|
||||
[ 6, 41 ] = wave (0) : "./MITfull/elev-30/L-30e246a.wav"
|
||||
[ 6, 42 ] = wave (0) : "./MITfull/elev-30/L-30e252a.wav"
|
||||
[ 6, 43 ] = wave (0) : "./MITfull/elev-30/L-30e258a.wav"
|
||||
[ 6, 44 ] = wave (0) : "./MITfull/elev-30/L-30e264a.wav"
|
||||
[ 6, 45 ] = wave (0) : "./MITfull/elev-30/L-30e270a.wav"
|
||||
[ 6, 46 ] = wave (0) : "./MITfull/elev-30/L-30e276a.wav"
|
||||
[ 6, 47 ] = wave (0) : "./MITfull/elev-30/L-30e282a.wav"
|
||||
[ 6, 48 ] = wave (0) : "./MITfull/elev-30/L-30e288a.wav"
|
||||
[ 6, 49 ] = wave (0) : "./MITfull/elev-30/L-30e294a.wav"
|
||||
[ 6, 50 ] = wave (0) : "./MITfull/elev-30/L-30e300a.wav"
|
||||
[ 6, 51 ] = wave (0) : "./MITfull/elev-30/L-30e306a.wav"
|
||||
[ 6, 52 ] = wave (0) : "./MITfull/elev-30/L-30e312a.wav"
|
||||
[ 6, 53 ] = wave (0) : "./MITfull/elev-30/L-30e318a.wav"
|
||||
[ 6, 54 ] = wave (0) : "./MITfull/elev-30/L-30e324a.wav"
|
||||
[ 6, 55 ] = wave (0) : "./MITfull/elev-30/L-30e330a.wav"
|
||||
[ 6, 56 ] = wave (0) : "./MITfull/elev-30/L-30e336a.wav"
|
||||
[ 6, 57 ] = wave (0) : "./MITfull/elev-30/L-30e342a.wav"
|
||||
[ 6, 58 ] = wave (0) : "./MITfull/elev-30/L-30e348a.wav"
|
||||
[ 6, 59 ] = wave (0) : "./MITfull/elev-30/L-30e354a.wav"
|
||||
|
||||
[ 7, 0 ] = wave (0) : "./MITfull/elev-20/L-20e000a.wav"
|
||||
[ 7, 1 ] = wave (0) : "./MITfull/elev-20/L-20e005a.wav"
|
||||
[ 7, 2 ] = wave (0) : "./MITfull/elev-20/L-20e010a.wav"
|
||||
[ 7, 3 ] = wave (0) : "./MITfull/elev-20/L-20e015a.wav"
|
||||
[ 7, 4 ] = wave (0) : "./MITfull/elev-20/L-20e020a.wav"
|
||||
[ 7, 5 ] = wave (0) : "./MITfull/elev-20/L-20e025a.wav"
|
||||
[ 7, 6 ] = wave (0) : "./MITfull/elev-20/L-20e030a.wav"
|
||||
[ 7, 7 ] = wave (0) : "./MITfull/elev-20/L-20e035a.wav"
|
||||
[ 7, 8 ] = wave (0) : "./MITfull/elev-20/L-20e040a.wav"
|
||||
[ 7, 9 ] = wave (0) : "./MITfull/elev-20/L-20e045a.wav"
|
||||
[ 7, 10 ] = wave (0) : "./MITfull/elev-20/L-20e050a.wav"
|
||||
[ 7, 11 ] = wave (0) : "./MITfull/elev-20/L-20e055a.wav"
|
||||
[ 7, 12 ] = wave (0) : "./MITfull/elev-20/L-20e060a.wav"
|
||||
[ 7, 13 ] = wave (0) : "./MITfull/elev-20/L-20e065a.wav"
|
||||
[ 7, 14 ] = wave (0) : "./MITfull/elev-20/L-20e070a.wav"
|
||||
[ 7, 15 ] = wave (0) : "./MITfull/elev-20/L-20e075a.wav"
|
||||
[ 7, 16 ] = wave (0) : "./MITfull/elev-20/L-20e080a.wav"
|
||||
[ 7, 17 ] = wave (0) : "./MITfull/elev-20/L-20e085a.wav"
|
||||
[ 7, 18 ] = wave (0) : "./MITfull/elev-20/L-20e090a.wav"
|
||||
[ 7, 19 ] = wave (0) : "./MITfull/elev-20/L-20e095a.wav"
|
||||
[ 7, 20 ] = wave (0) : "./MITfull/elev-20/L-20e100a.wav"
|
||||
[ 7, 21 ] = wave (0) : "./MITfull/elev-20/L-20e105a.wav"
|
||||
[ 7, 22 ] = wave (0) : "./MITfull/elev-20/L-20e110a.wav"
|
||||
[ 7, 23 ] = wave (0) : "./MITfull/elev-20/L-20e115a.wav"
|
||||
[ 7, 24 ] = wave (0) : "./MITfull/elev-20/L-20e120a.wav"
|
||||
[ 7, 25 ] = wave (0) : "./MITfull/elev-20/L-20e125a.wav"
|
||||
[ 7, 26 ] = wave (0) : "./MITfull/elev-20/L-20e130a.wav"
|
||||
[ 7, 27 ] = wave (0) : "./MITfull/elev-20/L-20e135a.wav"
|
||||
[ 7, 28 ] = wave (0) : "./MITfull/elev-20/L-20e140a.wav"
|
||||
[ 7, 29 ] = wave (0) : "./MITfull/elev-20/L-20e145a.wav"
|
||||
[ 7, 30 ] = wave (0) : "./MITfull/elev-20/L-20e150a.wav"
|
||||
[ 7, 31 ] = wave (0) : "./MITfull/elev-20/L-20e155a.wav"
|
||||
[ 7, 32 ] = wave (0) : "./MITfull/elev-20/L-20e160a.wav"
|
||||
[ 7, 33 ] = wave (0) : "./MITfull/elev-20/L-20e165a.wav"
|
||||
[ 7, 34 ] = wave (0) : "./MITfull/elev-20/L-20e170a.wav"
|
||||
[ 7, 35 ] = wave (0) : "./MITfull/elev-20/L-20e175a.wav"
|
||||
[ 7, 36 ] = wave (0) : "./MITfull/elev-20/L-20e180a.wav"
|
||||
[ 7, 37 ] = wave (0) : "./MITfull/elev-20/L-20e185a.wav"
|
||||
[ 7, 38 ] = wave (0) : "./MITfull/elev-20/L-20e190a.wav"
|
||||
[ 7, 39 ] = wave (0) : "./MITfull/elev-20/L-20e195a.wav"
|
||||
[ 7, 40 ] = wave (0) : "./MITfull/elev-20/L-20e200a.wav"
|
||||
[ 7, 41 ] = wave (0) : "./MITfull/elev-20/L-20e205a.wav"
|
||||
[ 7, 42 ] = wave (0) : "./MITfull/elev-20/L-20e210a.wav"
|
||||
[ 7, 43 ] = wave (0) : "./MITfull/elev-20/L-20e215a.wav"
|
||||
[ 7, 44 ] = wave (0) : "./MITfull/elev-20/L-20e220a.wav"
|
||||
[ 7, 45 ] = wave (0) : "./MITfull/elev-20/L-20e225a.wav"
|
||||
[ 7, 46 ] = wave (0) : "./MITfull/elev-20/L-20e230a.wav"
|
||||
[ 7, 47 ] = wave (0) : "./MITfull/elev-20/L-20e235a.wav"
|
||||
[ 7, 48 ] = wave (0) : "./MITfull/elev-20/L-20e240a.wav"
|
||||
[ 7, 49 ] = wave (0) : "./MITfull/elev-20/L-20e245a.wav"
|
||||
[ 7, 50 ] = wave (0) : "./MITfull/elev-20/L-20e250a.wav"
|
||||
[ 7, 51 ] = wave (0) : "./MITfull/elev-20/L-20e255a.wav"
|
||||
[ 7, 52 ] = wave (0) : "./MITfull/elev-20/L-20e260a.wav"
|
||||
[ 7, 53 ] = wave (0) : "./MITfull/elev-20/L-20e265a.wav"
|
||||
[ 7, 54 ] = wave (0) : "./MITfull/elev-20/L-20e270a.wav"
|
||||
[ 7, 55 ] = wave (0) : "./MITfull/elev-20/L-20e275a.wav"
|
||||
[ 7, 56 ] = wave (0) : "./MITfull/elev-20/L-20e280a.wav"
|
||||
[ 7, 57 ] = wave (0) : "./MITfull/elev-20/L-20e285a.wav"
|
||||
[ 7, 58 ] = wave (0) : "./MITfull/elev-20/L-20e290a.wav"
|
||||
[ 7, 59 ] = wave (0) : "./MITfull/elev-20/L-20e295a.wav"
|
||||
[ 7, 60 ] = wave (0) : "./MITfull/elev-20/L-20e300a.wav"
|
||||
[ 7, 61 ] = wave (0) : "./MITfull/elev-20/L-20e305a.wav"
|
||||
[ 7, 62 ] = wave (0) : "./MITfull/elev-20/L-20e310a.wav"
|
||||
[ 7, 63 ] = wave (0) : "./MITfull/elev-20/L-20e315a.wav"
|
||||
[ 7, 64 ] = wave (0) : "./MITfull/elev-20/L-20e320a.wav"
|
||||
[ 7, 65 ] = wave (0) : "./MITfull/elev-20/L-20e325a.wav"
|
||||
[ 7, 66 ] = wave (0) : "./MITfull/elev-20/L-20e330a.wav"
|
||||
[ 7, 67 ] = wave (0) : "./MITfull/elev-20/L-20e335a.wav"
|
||||
[ 7, 68 ] = wave (0) : "./MITfull/elev-20/L-20e340a.wav"
|
||||
[ 7, 69 ] = wave (0) : "./MITfull/elev-20/L-20e345a.wav"
|
||||
[ 7, 70 ] = wave (0) : "./MITfull/elev-20/L-20e350a.wav"
|
||||
[ 7, 71 ] = wave (0) : "./MITfull/elev-20/L-20e355a.wav"
|
||||
|
||||
[ 8, 0 ] = wave (0) : "./MITfull/elev-10/L-10e000a.wav"
|
||||
[ 8, 1 ] = wave (0) : "./MITfull/elev-10/L-10e005a.wav"
|
||||
[ 8, 2 ] = wave (0) : "./MITfull/elev-10/L-10e010a.wav"
|
||||
[ 8, 3 ] = wave (0) : "./MITfull/elev-10/L-10e015a.wav"
|
||||
[ 8, 4 ] = wave (0) : "./MITfull/elev-10/L-10e020a.wav"
|
||||
[ 8, 5 ] = wave (0) : "./MITfull/elev-10/L-10e025a.wav"
|
||||
[ 8, 6 ] = wave (0) : "./MITfull/elev-10/L-10e030a.wav"
|
||||
[ 8, 7 ] = wave (0) : "./MITfull/elev-10/L-10e035a.wav"
|
||||
[ 8, 8 ] = wave (0) : "./MITfull/elev-10/L-10e040a.wav"
|
||||
[ 8, 9 ] = wave (0) : "./MITfull/elev-10/L-10e045a.wav"
|
||||
[ 8, 10 ] = wave (0) : "./MITfull/elev-10/L-10e050a.wav"
|
||||
[ 8, 11 ] = wave (0) : "./MITfull/elev-10/L-10e055a.wav"
|
||||
[ 8, 12 ] = wave (0) : "./MITfull/elev-10/L-10e060a.wav"
|
||||
[ 8, 13 ] = wave (0) : "./MITfull/elev-10/L-10e065a.wav"
|
||||
[ 8, 14 ] = wave (0) : "./MITfull/elev-10/L-10e070a.wav"
|
||||
[ 8, 15 ] = wave (0) : "./MITfull/elev-10/L-10e075a.wav"
|
||||
[ 8, 16 ] = wave (0) : "./MITfull/elev-10/L-10e080a.wav"
|
||||
[ 8, 17 ] = wave (0) : "./MITfull/elev-10/L-10e085a.wav"
|
||||
[ 8, 18 ] = wave (0) : "./MITfull/elev-10/L-10e090a.wav"
|
||||
[ 8, 19 ] = wave (0) : "./MITfull/elev-10/L-10e095a.wav"
|
||||
[ 8, 20 ] = wave (0) : "./MITfull/elev-10/L-10e100a.wav"
|
||||
[ 8, 21 ] = wave (0) : "./MITfull/elev-10/L-10e105a.wav"
|
||||
[ 8, 22 ] = wave (0) : "./MITfull/elev-10/L-10e110a.wav"
|
||||
[ 8, 23 ] = wave (0) : "./MITfull/elev-10/L-10e115a.wav"
|
||||
[ 8, 24 ] = wave (0) : "./MITfull/elev-10/L-10e120a.wav"
|
||||
[ 8, 25 ] = wave (0) : "./MITfull/elev-10/L-10e125a.wav"
|
||||
[ 8, 26 ] = wave (0) : "./MITfull/elev-10/L-10e130a.wav"
|
||||
[ 8, 27 ] = wave (0) : "./MITfull/elev-10/L-10e135a.wav"
|
||||
[ 8, 28 ] = wave (0) : "./MITfull/elev-10/L-10e140a.wav"
|
||||
[ 8, 29 ] = wave (0) : "./MITfull/elev-10/L-10e145a.wav"
|
||||
[ 8, 30 ] = wave (0) : "./MITfull/elev-10/L-10e150a.wav"
|
||||
[ 8, 31 ] = wave (0) : "./MITfull/elev-10/L-10e155a.wav"
|
||||
[ 8, 32 ] = wave (0) : "./MITfull/elev-10/L-10e160a.wav"
|
||||
[ 8, 33 ] = wave (0) : "./MITfull/elev-10/L-10e165a.wav"
|
||||
[ 8, 34 ] = wave (0) : "./MITfull/elev-10/L-10e170a.wav"
|
||||
[ 8, 35 ] = wave (0) : "./MITfull/elev-10/L-10e175a.wav"
|
||||
[ 8, 36 ] = wave (0) : "./MITfull/elev-10/L-10e180a.wav"
|
||||
[ 8, 37 ] = wave (0) : "./MITfull/elev-10/L-10e185a.wav"
|
||||
[ 8, 38 ] = wave (0) : "./MITfull/elev-10/L-10e190a.wav"
|
||||
[ 8, 39 ] = wave (0) : "./MITfull/elev-10/L-10e195a.wav"
|
||||
[ 8, 40 ] = wave (0) : "./MITfull/elev-10/L-10e200a.wav"
|
||||
[ 8, 41 ] = wave (0) : "./MITfull/elev-10/L-10e205a.wav"
|
||||
[ 8, 42 ] = wave (0) : "./MITfull/elev-10/L-10e210a.wav"
|
||||
[ 8, 43 ] = wave (0) : "./MITfull/elev-10/L-10e215a.wav"
|
||||
[ 8, 44 ] = wave (0) : "./MITfull/elev-10/L-10e220a.wav"
|
||||
[ 8, 45 ] = wave (0) : "./MITfull/elev-10/L-10e225a.wav"
|
||||
[ 8, 46 ] = wave (0) : "./MITfull/elev-10/L-10e230a.wav"
|
||||
[ 8, 47 ] = wave (0) : "./MITfull/elev-10/L-10e235a.wav"
|
||||
[ 8, 48 ] = wave (0) : "./MITfull/elev-10/L-10e240a.wav"
|
||||
[ 8, 49 ] = wave (0) : "./MITfull/elev-10/L-10e245a.wav"
|
||||
[ 8, 50 ] = wave (0) : "./MITfull/elev-10/L-10e250a.wav"
|
||||
[ 8, 51 ] = wave (0) : "./MITfull/elev-10/L-10e255a.wav"
|
||||
[ 8, 52 ] = wave (0) : "./MITfull/elev-10/L-10e260a.wav"
|
||||
[ 8, 53 ] = wave (0) : "./MITfull/elev-10/L-10e265a.wav"
|
||||
[ 8, 54 ] = wave (0) : "./MITfull/elev-10/L-10e270a.wav"
|
||||
[ 8, 55 ] = wave (0) : "./MITfull/elev-10/L-10e275a.wav"
|
||||
[ 8, 56 ] = wave (0) : "./MITfull/elev-10/L-10e280a.wav"
|
||||
[ 8, 57 ] = wave (0) : "./MITfull/elev-10/L-10e285a.wav"
|
||||
[ 8, 58 ] = wave (0) : "./MITfull/elev-10/L-10e290a.wav"
|
||||
[ 8, 59 ] = wave (0) : "./MITfull/elev-10/L-10e295a.wav"
|
||||
[ 8, 60 ] = wave (0) : "./MITfull/elev-10/L-10e300a.wav"
|
||||
[ 8, 61 ] = wave (0) : "./MITfull/elev-10/L-10e305a.wav"
|
||||
[ 8, 62 ] = wave (0) : "./MITfull/elev-10/L-10e310a.wav"
|
||||
[ 8, 63 ] = wave (0) : "./MITfull/elev-10/L-10e315a.wav"
|
||||
[ 8, 64 ] = wave (0) : "./MITfull/elev-10/L-10e320a.wav"
|
||||
[ 8, 65 ] = wave (0) : "./MITfull/elev-10/L-10e325a.wav"
|
||||
[ 8, 66 ] = wave (0) : "./MITfull/elev-10/L-10e330a.wav"
|
||||
[ 8, 67 ] = wave (0) : "./MITfull/elev-10/L-10e335a.wav"
|
||||
[ 8, 68 ] = wave (0) : "./MITfull/elev-10/L-10e340a.wav"
|
||||
[ 8, 69 ] = wave (0) : "./MITfull/elev-10/L-10e345a.wav"
|
||||
[ 8, 70 ] = wave (0) : "./MITfull/elev-10/L-10e350a.wav"
|
||||
[ 8, 71 ] = wave (0) : "./MITfull/elev-10/L-10e355a.wav"
|
||||
|
||||
[ 9, 0 ] = wave (0) : "./MITfull/elev0/L0e000a.wav"
|
||||
[ 9, 1 ] = wave (0) : "./MITfull/elev0/L0e005a.wav"
|
||||
[ 9, 2 ] = wave (0) : "./MITfull/elev0/L0e010a.wav"
|
||||
[ 9, 3 ] = wave (0) : "./MITfull/elev0/L0e015a.wav"
|
||||
[ 9, 4 ] = wave (0) : "./MITfull/elev0/L0e020a.wav"
|
||||
[ 9, 5 ] = wave (0) : "./MITfull/elev0/L0e025a.wav"
|
||||
[ 9, 6 ] = wave (0) : "./MITfull/elev0/L0e030a.wav"
|
||||
[ 9, 7 ] = wave (0) : "./MITfull/elev0/L0e035a.wav"
|
||||
[ 9, 8 ] = wave (0) : "./MITfull/elev0/L0e040a.wav"
|
||||
[ 9, 9 ] = wave (0) : "./MITfull/elev0/L0e045a.wav"
|
||||
[ 9, 10 ] = wave (0) : "./MITfull/elev0/L0e050a.wav"
|
||||
[ 9, 11 ] = wave (0) : "./MITfull/elev0/L0e055a.wav"
|
||||
[ 9, 12 ] = wave (0) : "./MITfull/elev0/L0e060a.wav"
|
||||
[ 9, 13 ] = wave (0) : "./MITfull/elev0/L0e065a.wav"
|
||||
[ 9, 14 ] = wave (0) : "./MITfull/elev0/L0e070a.wav"
|
||||
[ 9, 15 ] = wave (0) : "./MITfull/elev0/L0e075a.wav"
|
||||
[ 9, 16 ] = wave (0) : "./MITfull/elev0/L0e080a.wav"
|
||||
[ 9, 17 ] = wave (0) : "./MITfull/elev0/L0e085a.wav"
|
||||
[ 9, 18 ] = wave (0) : "./MITfull/elev0/L0e090a.wav"
|
||||
[ 9, 19 ] = wave (0) : "./MITfull/elev0/L0e095a.wav"
|
||||
[ 9, 20 ] = wave (0) : "./MITfull/elev0/L0e100a.wav"
|
||||
[ 9, 21 ] = wave (0) : "./MITfull/elev0/L0e105a.wav"
|
||||
[ 9, 22 ] = wave (0) : "./MITfull/elev0/L0e110a.wav"
|
||||
[ 9, 23 ] = wave (0) : "./MITfull/elev0/L0e115a.wav"
|
||||
[ 9, 24 ] = wave (0) : "./MITfull/elev0/L0e120a.wav"
|
||||
[ 9, 25 ] = wave (0) : "./MITfull/elev0/L0e125a.wav"
|
||||
[ 9, 26 ] = wave (0) : "./MITfull/elev0/L0e130a.wav"
|
||||
[ 9, 27 ] = wave (0) : "./MITfull/elev0/L0e135a.wav"
|
||||
[ 9, 28 ] = wave (0) : "./MITfull/elev0/L0e140a.wav"
|
||||
[ 9, 29 ] = wave (0) : "./MITfull/elev0/L0e145a.wav"
|
||||
[ 9, 30 ] = wave (0) : "./MITfull/elev0/L0e150a.wav"
|
||||
[ 9, 31 ] = wave (0) : "./MITfull/elev0/L0e155a.wav"
|
||||
[ 9, 32 ] = wave (0) : "./MITfull/elev0/L0e160a.wav"
|
||||
[ 9, 33 ] = wave (0) : "./MITfull/elev0/L0e165a.wav"
|
||||
[ 9, 34 ] = wave (0) : "./MITfull/elev0/L0e170a.wav"
|
||||
[ 9, 35 ] = wave (0) : "./MITfull/elev0/L0e175a.wav"
|
||||
[ 9, 36 ] = wave (0) : "./MITfull/elev0/L0e180a.wav"
|
||||
[ 9, 37 ] = wave (0) : "./MITfull/elev0/L0e185a.wav"
|
||||
[ 9, 38 ] = wave (0) : "./MITfull/elev0/L0e190a.wav"
|
||||
[ 9, 39 ] = wave (0) : "./MITfull/elev0/L0e195a.wav"
|
||||
[ 9, 40 ] = wave (0) : "./MITfull/elev0/L0e200a.wav"
|
||||
[ 9, 41 ] = wave (0) : "./MITfull/elev0/L0e205a.wav"
|
||||
[ 9, 42 ] = wave (0) : "./MITfull/elev0/L0e210a.wav"
|
||||
[ 9, 43 ] = wave (0) : "./MITfull/elev0/L0e215a.wav"
|
||||
[ 9, 44 ] = wave (0) : "./MITfull/elev0/L0e220a.wav"
|
||||
[ 9, 45 ] = wave (0) : "./MITfull/elev0/L0e225a.wav"
|
||||
[ 9, 46 ] = wave (0) : "./MITfull/elev0/L0e230a.wav"
|
||||
[ 9, 47 ] = wave (0) : "./MITfull/elev0/L0e235a.wav"
|
||||
[ 9, 48 ] = wave (0) : "./MITfull/elev0/L0e240a.wav"
|
||||
[ 9, 49 ] = wave (0) : "./MITfull/elev0/L0e245a.wav"
|
||||
[ 9, 50 ] = wave (0) : "./MITfull/elev0/L0e250a.wav"
|
||||
[ 9, 51 ] = wave (0) : "./MITfull/elev0/L0e255a.wav"
|
||||
[ 9, 52 ] = wave (0) : "./MITfull/elev0/L0e260a.wav"
|
||||
[ 9, 53 ] = wave (0) : "./MITfull/elev0/L0e265a.wav"
|
||||
[ 9, 54 ] = wave (0) : "./MITfull/elev0/L0e270a.wav"
|
||||
[ 9, 55 ] = wave (0) : "./MITfull/elev0/L0e275a.wav"
|
||||
[ 9, 56 ] = wave (0) : "./MITfull/elev0/L0e280a.wav"
|
||||
[ 9, 57 ] = wave (0) : "./MITfull/elev0/L0e285a.wav"
|
||||
[ 9, 58 ] = wave (0) : "./MITfull/elev0/L0e290a.wav"
|
||||
[ 9, 59 ] = wave (0) : "./MITfull/elev0/L0e295a.wav"
|
||||
[ 9, 60 ] = wave (0) : "./MITfull/elev0/L0e300a.wav"
|
||||
[ 9, 61 ] = wave (0) : "./MITfull/elev0/L0e305a.wav"
|
||||
[ 9, 62 ] = wave (0) : "./MITfull/elev0/L0e310a.wav"
|
||||
[ 9, 63 ] = wave (0) : "./MITfull/elev0/L0e315a.wav"
|
||||
[ 9, 64 ] = wave (0) : "./MITfull/elev0/L0e320a.wav"
|
||||
[ 9, 65 ] = wave (0) : "./MITfull/elev0/L0e325a.wav"
|
||||
[ 9, 66 ] = wave (0) : "./MITfull/elev0/L0e330a.wav"
|
||||
[ 9, 67 ] = wave (0) : "./MITfull/elev0/L0e335a.wav"
|
||||
[ 9, 68 ] = wave (0) : "./MITfull/elev0/L0e340a.wav"
|
||||
[ 9, 69 ] = wave (0) : "./MITfull/elev0/L0e345a.wav"
|
||||
[ 9, 70 ] = wave (0) : "./MITfull/elev0/L0e350a.wav"
|
||||
[ 9, 71 ] = wave (0) : "./MITfull/elev0/L0e355a.wav"
|
||||
|
||||
[ 10, 0 ] = wave (0) : "./MITfull/elev10/L10e000a.wav"
|
||||
[ 10, 1 ] = wave (0) : "./MITfull/elev10/L10e005a.wav"
|
||||
[ 10, 2 ] = wave (0) : "./MITfull/elev10/L10e010a.wav"
|
||||
[ 10, 3 ] = wave (0) : "./MITfull/elev10/L10e015a.wav"
|
||||
[ 10, 4 ] = wave (0) : "./MITfull/elev10/L10e020a.wav"
|
||||
[ 10, 5 ] = wave (0) : "./MITfull/elev10/L10e025a.wav"
|
||||
[ 10, 6 ] = wave (0) : "./MITfull/elev10/L10e030a.wav"
|
||||
[ 10, 7 ] = wave (0) : "./MITfull/elev10/L10e035a.wav"
|
||||
[ 10, 8 ] = wave (0) : "./MITfull/elev10/L10e040a.wav"
|
||||
[ 10, 9 ] = wave (0) : "./MITfull/elev10/L10e045a.wav"
|
||||
[ 10, 10 ] = wave (0) : "./MITfull/elev10/L10e050a.wav"
|
||||
[ 10, 11 ] = wave (0) : "./MITfull/elev10/L10e055a.wav"
|
||||
[ 10, 12 ] = wave (0) : "./MITfull/elev10/L10e060a.wav"
|
||||
[ 10, 13 ] = wave (0) : "./MITfull/elev10/L10e065a.wav"
|
||||
[ 10, 14 ] = wave (0) : "./MITfull/elev10/L10e070a.wav"
|
||||
[ 10, 15 ] = wave (0) : "./MITfull/elev10/L10e075a.wav"
|
||||
[ 10, 16 ] = wave (0) : "./MITfull/elev10/L10e080a.wav"
|
||||
[ 10, 17 ] = wave (0) : "./MITfull/elev10/L10e085a.wav"
|
||||
[ 10, 18 ] = wave (0) : "./MITfull/elev10/L10e090a.wav"
|
||||
[ 10, 19 ] = wave (0) : "./MITfull/elev10/L10e095a.wav"
|
||||
[ 10, 20 ] = wave (0) : "./MITfull/elev10/L10e100a.wav"
|
||||
[ 10, 21 ] = wave (0) : "./MITfull/elev10/L10e105a.wav"
|
||||
[ 10, 22 ] = wave (0) : "./MITfull/elev10/L10e110a.wav"
|
||||
[ 10, 23 ] = wave (0) : "./MITfull/elev10/L10e115a.wav"
|
||||
[ 10, 24 ] = wave (0) : "./MITfull/elev10/L10e120a.wav"
|
||||
[ 10, 25 ] = wave (0) : "./MITfull/elev10/L10e125a.wav"
|
||||
[ 10, 26 ] = wave (0) : "./MITfull/elev10/L10e130a.wav"
|
||||
[ 10, 27 ] = wave (0) : "./MITfull/elev10/L10e135a.wav"
|
||||
[ 10, 28 ] = wave (0) : "./MITfull/elev10/L10e140a.wav"
|
||||
[ 10, 29 ] = wave (0) : "./MITfull/elev10/L10e145a.wav"
|
||||
[ 10, 30 ] = wave (0) : "./MITfull/elev10/L10e150a.wav"
|
||||
[ 10, 31 ] = wave (0) : "./MITfull/elev10/L10e155a.wav"
|
||||
[ 10, 32 ] = wave (0) : "./MITfull/elev10/L10e160a.wav"
|
||||
[ 10, 33 ] = wave (0) : "./MITfull/elev10/L10e165a.wav"
|
||||
[ 10, 34 ] = wave (0) : "./MITfull/elev10/L10e170a.wav"
|
||||
[ 10, 35 ] = wave (0) : "./MITfull/elev10/L10e175a.wav"
|
||||
[ 10, 36 ] = wave (0) : "./MITfull/elev10/L10e180a.wav"
|
||||
[ 10, 37 ] = wave (0) : "./MITfull/elev10/L10e185a.wav"
|
||||
[ 10, 38 ] = wave (0) : "./MITfull/elev10/L10e190a.wav"
|
||||
[ 10, 39 ] = wave (0) : "./MITfull/elev10/L10e195a.wav"
|
||||
[ 10, 40 ] = wave (0) : "./MITfull/elev10/L10e200a.wav"
|
||||
[ 10, 41 ] = wave (0) : "./MITfull/elev10/L10e205a.wav"
|
||||
[ 10, 42 ] = wave (0) : "./MITfull/elev10/L10e210a.wav"
|
||||
[ 10, 43 ] = wave (0) : "./MITfull/elev10/L10e215a.wav"
|
||||
[ 10, 44 ] = wave (0) : "./MITfull/elev10/L10e220a.wav"
|
||||
[ 10, 45 ] = wave (0) : "./MITfull/elev10/L10e225a.wav"
|
||||
[ 10, 46 ] = wave (0) : "./MITfull/elev10/L10e230a.wav"
|
||||
[ 10, 47 ] = wave (0) : "./MITfull/elev10/L10e235a.wav"
|
||||
[ 10, 48 ] = wave (0) : "./MITfull/elev10/L10e240a.wav"
|
||||
[ 10, 49 ] = wave (0) : "./MITfull/elev10/L10e245a.wav"
|
||||
[ 10, 50 ] = wave (0) : "./MITfull/elev10/L10e250a.wav"
|
||||
[ 10, 51 ] = wave (0) : "./MITfull/elev10/L10e255a.wav"
|
||||
[ 10, 52 ] = wave (0) : "./MITfull/elev10/L10e260a.wav"
|
||||
[ 10, 53 ] = wave (0) : "./MITfull/elev10/L10e265a.wav"
|
||||
[ 10, 54 ] = wave (0) : "./MITfull/elev10/L10e270a.wav"
|
||||
[ 10, 55 ] = wave (0) : "./MITfull/elev10/L10e275a.wav"
|
||||
[ 10, 56 ] = wave (0) : "./MITfull/elev10/L10e280a.wav"
|
||||
[ 10, 57 ] = wave (0) : "./MITfull/elev10/L10e285a.wav"
|
||||
[ 10, 58 ] = wave (0) : "./MITfull/elev10/L10e290a.wav"
|
||||
[ 10, 59 ] = wave (0) : "./MITfull/elev10/L10e295a.wav"
|
||||
[ 10, 60 ] = wave (0) : "./MITfull/elev10/L10e300a.wav"
|
||||
[ 10, 61 ] = wave (0) : "./MITfull/elev10/L10e305a.wav"
|
||||
[ 10, 62 ] = wave (0) : "./MITfull/elev10/L10e310a.wav"
|
||||
[ 10, 63 ] = wave (0) : "./MITfull/elev10/L10e315a.wav"
|
||||
[ 10, 64 ] = wave (0) : "./MITfull/elev10/L10e320a.wav"
|
||||
[ 10, 65 ] = wave (0) : "./MITfull/elev10/L10e325a.wav"
|
||||
[ 10, 66 ] = wave (0) : "./MITfull/elev10/L10e330a.wav"
|
||||
[ 10, 67 ] = wave (0) : "./MITfull/elev10/L10e335a.wav"
|
||||
[ 10, 68 ] = wave (0) : "./MITfull/elev10/L10e340a.wav"
|
||||
[ 10, 69 ] = wave (0) : "./MITfull/elev10/L10e345a.wav"
|
||||
[ 10, 70 ] = wave (0) : "./MITfull/elev10/L10e350a.wav"
|
||||
[ 10, 71 ] = wave (0) : "./MITfull/elev10/L10e355a.wav"
|
||||
|
||||
[ 11, 0 ] = wave (0) : "./MITfull/elev20/L20e000a.wav"
|
||||
[ 11, 1 ] = wave (0) : "./MITfull/elev20/L20e005a.wav"
|
||||
[ 11, 2 ] = wave (0) : "./MITfull/elev20/L20e010a.wav"
|
||||
[ 11, 3 ] = wave (0) : "./MITfull/elev20/L20e015a.wav"
|
||||
[ 11, 4 ] = wave (0) : "./MITfull/elev20/L20e020a.wav"
|
||||
[ 11, 5 ] = wave (0) : "./MITfull/elev20/L20e025a.wav"
|
||||
[ 11, 6 ] = wave (0) : "./MITfull/elev20/L20e030a.wav"
|
||||
[ 11, 7 ] = wave (0) : "./MITfull/elev20/L20e035a.wav"
|
||||
[ 11, 8 ] = wave (0) : "./MITfull/elev20/L20e040a.wav"
|
||||
[ 11, 9 ] = wave (0) : "./MITfull/elev20/L20e045a.wav"
|
||||
[ 11, 10 ] = wave (0) : "./MITfull/elev20/L20e050a.wav"
|
||||
[ 11, 11 ] = wave (0) : "./MITfull/elev20/L20e055a.wav"
|
||||
[ 11, 12 ] = wave (0) : "./MITfull/elev20/L20e060a.wav"
|
||||
[ 11, 13 ] = wave (0) : "./MITfull/elev20/L20e065a.wav"
|
||||
[ 11, 14 ] = wave (0) : "./MITfull/elev20/L20e070a.wav"
|
||||
[ 11, 15 ] = wave (0) : "./MITfull/elev20/L20e075a.wav"
|
||||
[ 11, 16 ] = wave (0) : "./MITfull/elev20/L20e080a.wav"
|
||||
[ 11, 17 ] = wave (0) : "./MITfull/elev20/L20e085a.wav"
|
||||
[ 11, 18 ] = wave (0) : "./MITfull/elev20/L20e090a.wav"
|
||||
[ 11, 19 ] = wave (0) : "./MITfull/elev20/L20e095a.wav"
|
||||
[ 11, 20 ] = wave (0) : "./MITfull/elev20/L20e100a.wav"
|
||||
[ 11, 21 ] = wave (0) : "./MITfull/elev20/L20e105a.wav"
|
||||
[ 11, 22 ] = wave (0) : "./MITfull/elev20/L20e110a.wav"
|
||||
[ 11, 23 ] = wave (0) : "./MITfull/elev20/L20e115a.wav"
|
||||
[ 11, 24 ] = wave (0) : "./MITfull/elev20/L20e120a.wav"
|
||||
[ 11, 25 ] = wave (0) : "./MITfull/elev20/L20e125a.wav"
|
||||
[ 11, 26 ] = wave (0) : "./MITfull/elev20/L20e130a.wav"
|
||||
[ 11, 27 ] = wave (0) : "./MITfull/elev20/L20e135a.wav"
|
||||
[ 11, 28 ] = wave (0) : "./MITfull/elev20/L20e140a.wav"
|
||||
[ 11, 29 ] = wave (0) : "./MITfull/elev20/L20e145a.wav"
|
||||
[ 11, 30 ] = wave (0) : "./MITfull/elev20/L20e150a.wav"
|
||||
[ 11, 31 ] = wave (0) : "./MITfull/elev20/L20e155a.wav"
|
||||
[ 11, 32 ] = wave (0) : "./MITfull/elev20/L20e160a.wav"
|
||||
[ 11, 33 ] = wave (0) : "./MITfull/elev20/L20e165a.wav"
|
||||
[ 11, 34 ] = wave (0) : "./MITfull/elev20/L20e170a.wav"
|
||||
[ 11, 35 ] = wave (0) : "./MITfull/elev20/L20e175a.wav"
|
||||
[ 11, 36 ] = wave (0) : "./MITfull/elev20/L20e180a.wav"
|
||||
[ 11, 37 ] = wave (0) : "./MITfull/elev20/L20e185a.wav"
|
||||
[ 11, 38 ] = wave (0) : "./MITfull/elev20/L20e190a.wav"
|
||||
[ 11, 39 ] = wave (0) : "./MITfull/elev20/L20e195a.wav"
|
||||
[ 11, 40 ] = wave (0) : "./MITfull/elev20/L20e200a.wav"
|
||||
[ 11, 41 ] = wave (0) : "./MITfull/elev20/L20e205a.wav"
|
||||
[ 11, 42 ] = wave (0) : "./MITfull/elev20/L20e210a.wav"
|
||||
[ 11, 43 ] = wave (0) : "./MITfull/elev20/L20e215a.wav"
|
||||
[ 11, 44 ] = wave (0) : "./MITfull/elev20/L20e220a.wav"
|
||||
[ 11, 45 ] = wave (0) : "./MITfull/elev20/L20e225a.wav"
|
||||
[ 11, 46 ] = wave (0) : "./MITfull/elev20/L20e230a.wav"
|
||||
[ 11, 47 ] = wave (0) : "./MITfull/elev20/L20e235a.wav"
|
||||
[ 11, 48 ] = wave (0) : "./MITfull/elev20/L20e240a.wav"
|
||||
[ 11, 49 ] = wave (0) : "./MITfull/elev20/L20e245a.wav"
|
||||
[ 11, 50 ] = wave (0) : "./MITfull/elev20/L20e250a.wav"
|
||||
[ 11, 51 ] = wave (0) : "./MITfull/elev20/L20e255a.wav"
|
||||
[ 11, 52 ] = wave (0) : "./MITfull/elev20/L20e260a.wav"
|
||||
[ 11, 53 ] = wave (0) : "./MITfull/elev20/L20e265a.wav"
|
||||
[ 11, 54 ] = wave (0) : "./MITfull/elev20/L20e270a.wav"
|
||||
[ 11, 55 ] = wave (0) : "./MITfull/elev20/L20e275a.wav"
|
||||
[ 11, 56 ] = wave (0) : "./MITfull/elev20/L20e280a.wav"
|
||||
[ 11, 57 ] = wave (0) : "./MITfull/elev20/L20e285a.wav"
|
||||
[ 11, 58 ] = wave (0) : "./MITfull/elev20/L20e290a.wav"
|
||||
[ 11, 59 ] = wave (0) : "./MITfull/elev20/L20e295a.wav"
|
||||
[ 11, 60 ] = wave (0) : "./MITfull/elev20/L20e300a.wav"
|
||||
[ 11, 61 ] = wave (0) : "./MITfull/elev20/L20e305a.wav"
|
||||
[ 11, 62 ] = wave (0) : "./MITfull/elev20/L20e310a.wav"
|
||||
[ 11, 63 ] = wave (0) : "./MITfull/elev20/L20e315a.wav"
|
||||
[ 11, 64 ] = wave (0) : "./MITfull/elev20/L20e320a.wav"
|
||||
[ 11, 65 ] = wave (0) : "./MITfull/elev20/L20e325a.wav"
|
||||
[ 11, 66 ] = wave (0) : "./MITfull/elev20/L20e330a.wav"
|
||||
[ 11, 67 ] = wave (0) : "./MITfull/elev20/L20e335a.wav"
|
||||
[ 11, 68 ] = wave (0) : "./MITfull/elev20/L20e340a.wav"
|
||||
[ 11, 69 ] = wave (0) : "./MITfull/elev20/L20e345a.wav"
|
||||
[ 11, 70 ] = wave (0) : "./MITfull/elev20/L20e350a.wav"
|
||||
[ 11, 71 ] = wave (0) : "./MITfull/elev20/L20e355a.wav"
|
||||
|
||||
[ 12, 0 ] = wave (0) : "./MITfull/elev30/L30e000a.wav"
|
||||
[ 12, 1 ] = wave (0) : "./MITfull/elev30/L30e006a.wav"
|
||||
[ 12, 2 ] = wave (0) : "./MITfull/elev30/L30e012a.wav"
|
||||
[ 12, 3 ] = wave (0) : "./MITfull/elev30/L30e018a.wav"
|
||||
[ 12, 4 ] = wave (0) : "./MITfull/elev30/L30e024a.wav"
|
||||
[ 12, 5 ] = wave (0) : "./MITfull/elev30/L30e030a.wav"
|
||||
[ 12, 6 ] = wave (0) : "./MITfull/elev30/L30e036a.wav"
|
||||
[ 12, 7 ] = wave (0) : "./MITfull/elev30/L30e042a.wav"
|
||||
[ 12, 8 ] = wave (0) : "./MITfull/elev30/L30e048a.wav"
|
||||
[ 12, 9 ] = wave (0) : "./MITfull/elev30/L30e054a.wav"
|
||||
[ 12, 10 ] = wave (0) : "./MITfull/elev30/L30e060a.wav"
|
||||
[ 12, 11 ] = wave (0) : "./MITfull/elev30/L30e066a.wav"
|
||||
[ 12, 12 ] = wave (0) : "./MITfull/elev30/L30e072a.wav"
|
||||
[ 12, 13 ] = wave (0) : "./MITfull/elev30/L30e078a.wav"
|
||||
[ 12, 14 ] = wave (0) : "./MITfull/elev30/L30e084a.wav"
|
||||
[ 12, 15 ] = wave (0) : "./MITfull/elev30/L30e090a.wav"
|
||||
[ 12, 16 ] = wave (0) : "./MITfull/elev30/L30e096a.wav"
|
||||
[ 12, 17 ] = wave (0) : "./MITfull/elev30/L30e102a.wav"
|
||||
[ 12, 18 ] = wave (0) : "./MITfull/elev30/L30e108a.wav"
|
||||
[ 12, 19 ] = wave (0) : "./MITfull/elev30/L30e114a.wav"
|
||||
[ 12, 20 ] = wave (0) : "./MITfull/elev30/L30e120a.wav"
|
||||
[ 12, 21 ] = wave (0) : "./MITfull/elev30/L30e126a.wav"
|
||||
[ 12, 22 ] = wave (0) : "./MITfull/elev30/L30e132a.wav"
|
||||
[ 12, 23 ] = wave (0) : "./MITfull/elev30/L30e138a.wav"
|
||||
[ 12, 24 ] = wave (0) : "./MITfull/elev30/L30e144a.wav"
|
||||
[ 12, 25 ] = wave (0) : "./MITfull/elev30/L30e150a.wav"
|
||||
[ 12, 26 ] = wave (0) : "./MITfull/elev30/L30e156a.wav"
|
||||
[ 12, 27 ] = wave (0) : "./MITfull/elev30/L30e162a.wav"
|
||||
[ 12, 28 ] = wave (0) : "./MITfull/elev30/L30e168a.wav"
|
||||
[ 12, 29 ] = wave (0) : "./MITfull/elev30/L30e174a.wav"
|
||||
[ 12, 30 ] = wave (0) : "./MITfull/elev30/L30e180a.wav"
|
||||
[ 12, 31 ] = wave (0) : "./MITfull/elev30/L30e186a.wav"
|
||||
[ 12, 32 ] = wave (0) : "./MITfull/elev30/L30e192a.wav"
|
||||
[ 12, 33 ] = wave (0) : "./MITfull/elev30/L30e198a.wav"
|
||||
[ 12, 34 ] = wave (0) : "./MITfull/elev30/L30e204a.wav"
|
||||
[ 12, 35 ] = wave (0) : "./MITfull/elev30/L30e210a.wav"
|
||||
[ 12, 36 ] = wave (0) : "./MITfull/elev30/L30e216a.wav"
|
||||
[ 12, 37 ] = wave (0) : "./MITfull/elev30/L30e222a.wav"
|
||||
[ 12, 38 ] = wave (0) : "./MITfull/elev30/L30e228a.wav"
|
||||
[ 12, 39 ] = wave (0) : "./MITfull/elev30/L30e234a.wav"
|
||||
[ 12, 40 ] = wave (0) : "./MITfull/elev30/L30e240a.wav"
|
||||
[ 12, 41 ] = wave (0) : "./MITfull/elev30/L30e246a.wav"
|
||||
[ 12, 42 ] = wave (0) : "./MITfull/elev30/L30e252a.wav"
|
||||
[ 12, 43 ] = wave (0) : "./MITfull/elev30/L30e258a.wav"
|
||||
[ 12, 44 ] = wave (0) : "./MITfull/elev30/L30e264a.wav"
|
||||
[ 12, 45 ] = wave (0) : "./MITfull/elev30/L30e270a.wav"
|
||||
[ 12, 46 ] = wave (0) : "./MITfull/elev30/L30e276a.wav"
|
||||
[ 12, 47 ] = wave (0) : "./MITfull/elev30/L30e282a.wav"
|
||||
[ 12, 48 ] = wave (0) : "./MITfull/elev30/L30e288a.wav"
|
||||
[ 12, 49 ] = wave (0) : "./MITfull/elev30/L30e294a.wav"
|
||||
[ 12, 50 ] = wave (0) : "./MITfull/elev30/L30e300a.wav"
|
||||
[ 12, 51 ] = wave (0) : "./MITfull/elev30/L30e306a.wav"
|
||||
[ 12, 52 ] = wave (0) : "./MITfull/elev30/L30e312a.wav"
|
||||
[ 12, 53 ] = wave (0) : "./MITfull/elev30/L30e318a.wav"
|
||||
[ 12, 54 ] = wave (0) : "./MITfull/elev30/L30e324a.wav"
|
||||
[ 12, 55 ] = wave (0) : "./MITfull/elev30/L30e330a.wav"
|
||||
[ 12, 56 ] = wave (0) : "./MITfull/elev30/L30e336a.wav"
|
||||
[ 12, 57 ] = wave (0) : "./MITfull/elev30/L30e342a.wav"
|
||||
[ 12, 58 ] = wave (0) : "./MITfull/elev30/L30e348a.wav"
|
||||
[ 12, 59 ] = wave (0) : "./MITfull/elev30/L30e354a.wav"
|
||||
|
||||
[ 13, 0 ] = wave (0) : "./MITfull/elev40/L40e000a.wav"
|
||||
[ 13, 1 ] = wave (0) : "./MITfull/elev40/L40e006a.wav"
|
||||
[ 13, 2 ] = wave (0) : "./MITfull/elev40/L40e013a.wav"
|
||||
[ 13, 3 ] = wave (0) : "./MITfull/elev40/L40e019a.wav"
|
||||
[ 13, 4 ] = wave (0) : "./MITfull/elev40/L40e026a.wav"
|
||||
[ 13, 5 ] = wave (0) : "./MITfull/elev40/L40e032a.wav"
|
||||
[ 13, 6 ] = wave (0) : "./MITfull/elev40/L40e039a.wav"
|
||||
[ 13, 7 ] = wave (0) : "./MITfull/elev40/L40e045a.wav"
|
||||
[ 13, 8 ] = wave (0) : "./MITfull/elev40/L40e051a.wav"
|
||||
[ 13, 9 ] = wave (0) : "./MITfull/elev40/L40e058a.wav"
|
||||
[ 13, 10 ] = wave (0) : "./MITfull/elev40/L40e064a.wav"
|
||||
[ 13, 11 ] = wave (0) : "./MITfull/elev40/L40e071a.wav"
|
||||
[ 13, 12 ] = wave (0) : "./MITfull/elev40/L40e077a.wav"
|
||||
[ 13, 13 ] = wave (0) : "./MITfull/elev40/L40e084a.wav"
|
||||
[ 13, 14 ] = wave (0) : "./MITfull/elev40/L40e090a.wav"
|
||||
[ 13, 15 ] = wave (0) : "./MITfull/elev40/L40e096a.wav"
|
||||
[ 13, 16 ] = wave (0) : "./MITfull/elev40/L40e103a.wav"
|
||||
[ 13, 17 ] = wave (0) : "./MITfull/elev40/L40e109a.wav"
|
||||
[ 13, 18 ] = wave (0) : "./MITfull/elev40/L40e116a.wav"
|
||||
[ 13, 19 ] = wave (0) : "./MITfull/elev40/L40e122a.wav"
|
||||
[ 13, 20 ] = wave (0) : "./MITfull/elev40/L40e129a.wav"
|
||||
[ 13, 21 ] = wave (0) : "./MITfull/elev40/L40e135a.wav"
|
||||
[ 13, 22 ] = wave (0) : "./MITfull/elev40/L40e141a.wav"
|
||||
[ 13, 23 ] = wave (0) : "./MITfull/elev40/L40e148a.wav"
|
||||
[ 13, 24 ] = wave (0) : "./MITfull/elev40/L40e154a.wav"
|
||||
[ 13, 25 ] = wave (0) : "./MITfull/elev40/L40e161a.wav"
|
||||
[ 13, 26 ] = wave (0) : "./MITfull/elev40/L40e167a.wav"
|
||||
[ 13, 27 ] = wave (0) : "./MITfull/elev40/L40e174a.wav"
|
||||
[ 13, 28 ] = wave (0) : "./MITfull/elev40/L40e180a.wav"
|
||||
[ 13, 29 ] = wave (0) : "./MITfull/elev40/L40e186a.wav"
|
||||
[ 13, 30 ] = wave (0) : "./MITfull/elev40/L40e193a.wav"
|
||||
[ 13, 31 ] = wave (0) : "./MITfull/elev40/L40e199a.wav"
|
||||
[ 13, 32 ] = wave (0) : "./MITfull/elev40/L40e206a.wav"
|
||||
[ 13, 33 ] = wave (0) : "./MITfull/elev40/L40e212a.wav"
|
||||
[ 13, 34 ] = wave (0) : "./MITfull/elev40/L40e219a.wav"
|
||||
[ 13, 35 ] = wave (0) : "./MITfull/elev40/L40e225a.wav"
|
||||
[ 13, 36 ] = wave (0) : "./MITfull/elev40/L40e231a.wav"
|
||||
[ 13, 37 ] = wave (0) : "./MITfull/elev40/L40e238a.wav"
|
||||
[ 13, 38 ] = wave (0) : "./MITfull/elev40/L40e244a.wav"
|
||||
[ 13, 39 ] = wave (0) : "./MITfull/elev40/L40e251a.wav"
|
||||
[ 13, 40 ] = wave (0) : "./MITfull/elev40/L40e257a.wav"
|
||||
[ 13, 41 ] = wave (0) : "./MITfull/elev40/L40e264a.wav"
|
||||
[ 13, 42 ] = wave (0) : "./MITfull/elev40/L40e270a.wav"
|
||||
[ 13, 43 ] = wave (0) : "./MITfull/elev40/L40e276a.wav"
|
||||
[ 13, 44 ] = wave (0) : "./MITfull/elev40/L40e283a.wav"
|
||||
[ 13, 45 ] = wave (0) : "./MITfull/elev40/L40e289a.wav"
|
||||
[ 13, 46 ] = wave (0) : "./MITfull/elev40/L40e296a.wav"
|
||||
[ 13, 47 ] = wave (0) : "./MITfull/elev40/L40e302a.wav"
|
||||
[ 13, 48 ] = wave (0) : "./MITfull/elev40/L40e309a.wav"
|
||||
[ 13, 49 ] = wave (0) : "./MITfull/elev40/L40e315a.wav"
|
||||
[ 13, 50 ] = wave (0) : "./MITfull/elev40/L40e321a.wav"
|
||||
[ 13, 51 ] = wave (0) : "./MITfull/elev40/L40e328a.wav"
|
||||
[ 13, 52 ] = wave (0) : "./MITfull/elev40/L40e334a.wav"
|
||||
[ 13, 53 ] = wave (0) : "./MITfull/elev40/L40e341a.wav"
|
||||
[ 13, 54 ] = wave (0) : "./MITfull/elev40/L40e347a.wav"
|
||||
[ 13, 55 ] = wave (0) : "./MITfull/elev40/L40e354a.wav"
|
||||
|
||||
[ 14, 0 ] = wave (0) : "./MITfull/elev50/L50e000a.wav"
|
||||
[ 14, 1 ] = wave (0) : "./MITfull/elev50/L50e008a.wav"
|
||||
[ 14, 2 ] = wave (0) : "./MITfull/elev50/L50e016a.wav"
|
||||
[ 14, 3 ] = wave (0) : "./MITfull/elev50/L50e024a.wav"
|
||||
[ 14, 4 ] = wave (0) : "./MITfull/elev50/L50e032a.wav"
|
||||
[ 14, 5 ] = wave (0) : "./MITfull/elev50/L50e040a.wav"
|
||||
[ 14, 6 ] = wave (0) : "./MITfull/elev50/L50e048a.wav"
|
||||
[ 14, 7 ] = wave (0) : "./MITfull/elev50/L50e056a.wav"
|
||||
[ 14, 8 ] = wave (0) : "./MITfull/elev50/L50e064a.wav"
|
||||
[ 14, 9 ] = wave (0) : "./MITfull/elev50/L50e072a.wav"
|
||||
[ 14, 10 ] = wave (0) : "./MITfull/elev50/L50e080a.wav"
|
||||
[ 14, 11 ] = wave (0) : "./MITfull/elev50/L50e088a.wav"
|
||||
[ 14, 12 ] = wave (0) : "./MITfull/elev50/L50e096a.wav"
|
||||
[ 14, 13 ] = wave (0) : "./MITfull/elev50/L50e104a.wav"
|
||||
[ 14, 14 ] = wave (0) : "./MITfull/elev50/L50e112a.wav"
|
||||
[ 14, 15 ] = wave (0) : "./MITfull/elev50/L50e120a.wav"
|
||||
[ 14, 16 ] = wave (0) : "./MITfull/elev50/L50e128a.wav"
|
||||
[ 14, 17 ] = wave (0) : "./MITfull/elev50/L50e136a.wav"
|
||||
[ 14, 18 ] = wave (0) : "./MITfull/elev50/L50e144a.wav"
|
||||
[ 14, 19 ] = wave (0) : "./MITfull/elev50/L50e152a.wav"
|
||||
[ 14, 20 ] = wave (0) : "./MITfull/elev50/L50e160a.wav"
|
||||
[ 14, 21 ] = wave (0) : "./MITfull/elev50/L50e168a.wav"
|
||||
[ 14, 22 ] = wave (0) : "./MITfull/elev50/L50e176a.wav"
|
||||
[ 14, 23 ] = wave (0) : "./MITfull/elev50/L50e184a.wav"
|
||||
[ 14, 24 ] = wave (0) : "./MITfull/elev50/L50e192a.wav"
|
||||
[ 14, 25 ] = wave (0) : "./MITfull/elev50/L50e200a.wav"
|
||||
[ 14, 26 ] = wave (0) : "./MITfull/elev50/L50e208a.wav"
|
||||
[ 14, 27 ] = wave (0) : "./MITfull/elev50/L50e216a.wav"
|
||||
[ 14, 28 ] = wave (0) : "./MITfull/elev50/L50e224a.wav"
|
||||
[ 14, 29 ] = wave (0) : "./MITfull/elev50/L50e232a.wav"
|
||||
[ 14, 30 ] = wave (0) : "./MITfull/elev50/L50e240a.wav"
|
||||
[ 14, 31 ] = wave (0) : "./MITfull/elev50/L50e248a.wav"
|
||||
[ 14, 32 ] = wave (0) : "./MITfull/elev50/L50e256a.wav"
|
||||
[ 14, 33 ] = wave (0) : "./MITfull/elev50/L50e264a.wav"
|
||||
[ 14, 34 ] = wave (0) : "./MITfull/elev50/L50e272a.wav"
|
||||
[ 14, 35 ] = wave (0) : "./MITfull/elev50/L50e280a.wav"
|
||||
[ 14, 36 ] = wave (0) : "./MITfull/elev50/L50e288a.wav"
|
||||
[ 14, 37 ] = wave (0) : "./MITfull/elev50/L50e296a.wav"
|
||||
[ 14, 38 ] = wave (0) : "./MITfull/elev50/L50e304a.wav"
|
||||
[ 14, 39 ] = wave (0) : "./MITfull/elev50/L50e312a.wav"
|
||||
[ 14, 40 ] = wave (0) : "./MITfull/elev50/L50e320a.wav"
|
||||
[ 14, 41 ] = wave (0) : "./MITfull/elev50/L50e328a.wav"
|
||||
[ 14, 42 ] = wave (0) : "./MITfull/elev50/L50e336a.wav"
|
||||
[ 14, 43 ] = wave (0) : "./MITfull/elev50/L50e344a.wav"
|
||||
[ 14, 44 ] = wave (0) : "./MITfull/elev50/L50e352a.wav"
|
||||
|
||||
[ 15, 0 ] = wave (0) : "./MITfull/elev60/L60e000a.wav"
|
||||
[ 15, 1 ] = wave (0) : "./MITfull/elev60/L60e010a.wav"
|
||||
[ 15, 2 ] = wave (0) : "./MITfull/elev60/L60e020a.wav"
|
||||
[ 15, 3 ] = wave (0) : "./MITfull/elev60/L60e030a.wav"
|
||||
[ 15, 4 ] = wave (0) : "./MITfull/elev60/L60e040a.wav"
|
||||
[ 15, 5 ] = wave (0) : "./MITfull/elev60/L60e050a.wav"
|
||||
[ 15, 6 ] = wave (0) : "./MITfull/elev60/L60e060a.wav"
|
||||
[ 15, 7 ] = wave (0) : "./MITfull/elev60/L60e070a.wav"
|
||||
[ 15, 8 ] = wave (0) : "./MITfull/elev60/L60e080a.wav"
|
||||
[ 15, 9 ] = wave (0) : "./MITfull/elev60/L60e090a.wav"
|
||||
[ 15, 10 ] = wave (0) : "./MITfull/elev60/L60e100a.wav"
|
||||
[ 15, 11 ] = wave (0) : "./MITfull/elev60/L60e110a.wav"
|
||||
[ 15, 12 ] = wave (0) : "./MITfull/elev60/L60e120a.wav"
|
||||
[ 15, 13 ] = wave (0) : "./MITfull/elev60/L60e130a.wav"
|
||||
[ 15, 14 ] = wave (0) : "./MITfull/elev60/L60e140a.wav"
|
||||
[ 15, 15 ] = wave (0) : "./MITfull/elev60/L60e150a.wav"
|
||||
[ 15, 16 ] = wave (0) : "./MITfull/elev60/L60e160a.wav"
|
||||
[ 15, 17 ] = wave (0) : "./MITfull/elev60/L60e170a.wav"
|
||||
[ 15, 18 ] = wave (0) : "./MITfull/elev60/L60e180a.wav"
|
||||
[ 15, 19 ] = wave (0) : "./MITfull/elev60/L60e190a.wav"
|
||||
[ 15, 20 ] = wave (0) : "./MITfull/elev60/L60e200a.wav"
|
||||
[ 15, 21 ] = wave (0) : "./MITfull/elev60/L60e210a.wav"
|
||||
[ 15, 22 ] = wave (0) : "./MITfull/elev60/L60e220a.wav"
|
||||
[ 15, 23 ] = wave (0) : "./MITfull/elev60/L60e230a.wav"
|
||||
[ 15, 24 ] = wave (0) : "./MITfull/elev60/L60e240a.wav"
|
||||
[ 15, 25 ] = wave (0) : "./MITfull/elev60/L60e250a.wav"
|
||||
[ 15, 26 ] = wave (0) : "./MITfull/elev60/L60e260a.wav"
|
||||
[ 15, 27 ] = wave (0) : "./MITfull/elev60/L60e270a.wav"
|
||||
[ 15, 28 ] = wave (0) : "./MITfull/elev60/L60e280a.wav"
|
||||
[ 15, 29 ] = wave (0) : "./MITfull/elev60/L60e290a.wav"
|
||||
[ 15, 30 ] = wave (0) : "./MITfull/elev60/L60e300a.wav"
|
||||
[ 15, 31 ] = wave (0) : "./MITfull/elev60/L60e310a.wav"
|
||||
[ 15, 32 ] = wave (0) : "./MITfull/elev60/L60e320a.wav"
|
||||
[ 15, 33 ] = wave (0) : "./MITfull/elev60/L60e330a.wav"
|
||||
[ 15, 34 ] = wave (0) : "./MITfull/elev60/L60e340a.wav"
|
||||
[ 15, 35 ] = wave (0) : "./MITfull/elev60/L60e350a.wav"
|
||||
|
||||
[ 16, 0 ] = wave (0) : "./MITfull/elev70/L70e000a.wav"
|
||||
[ 16, 1 ] = wave (0) : "./MITfull/elev70/L70e015a.wav"
|
||||
[ 16, 2 ] = wave (0) : "./MITfull/elev70/L70e030a.wav"
|
||||
[ 16, 3 ] = wave (0) : "./MITfull/elev70/L70e045a.wav"
|
||||
[ 16, 4 ] = wave (0) : "./MITfull/elev70/L70e060a.wav"
|
||||
[ 16, 5 ] = wave (0) : "./MITfull/elev70/L70e075a.wav"
|
||||
[ 16, 6 ] = wave (0) : "./MITfull/elev70/L70e090a.wav"
|
||||
[ 16, 7 ] = wave (0) : "./MITfull/elev70/L70e105a.wav"
|
||||
[ 16, 8 ] = wave (0) : "./MITfull/elev70/L70e120a.wav"
|
||||
[ 16, 9 ] = wave (0) : "./MITfull/elev70/L70e135a.wav"
|
||||
[ 16, 10 ] = wave (0) : "./MITfull/elev70/L70e150a.wav"
|
||||
[ 16, 11 ] = wave (0) : "./MITfull/elev70/L70e165a.wav"
|
||||
[ 16, 12 ] = wave (0) : "./MITfull/elev70/L70e180a.wav"
|
||||
[ 16, 13 ] = wave (0) : "./MITfull/elev70/L70e195a.wav"
|
||||
[ 16, 14 ] = wave (0) : "./MITfull/elev70/L70e210a.wav"
|
||||
[ 16, 15 ] = wave (0) : "./MITfull/elev70/L70e225a.wav"
|
||||
[ 16, 16 ] = wave (0) : "./MITfull/elev70/L70e240a.wav"
|
||||
[ 16, 17 ] = wave (0) : "./MITfull/elev70/L70e255a.wav"
|
||||
[ 16, 18 ] = wave (0) : "./MITfull/elev70/L70e270a.wav"
|
||||
[ 16, 19 ] = wave (0) : "./MITfull/elev70/L70e285a.wav"
|
||||
[ 16, 20 ] = wave (0) : "./MITfull/elev70/L70e300a.wav"
|
||||
[ 16, 21 ] = wave (0) : "./MITfull/elev70/L70e315a.wav"
|
||||
[ 16, 22 ] = wave (0) : "./MITfull/elev70/L70e330a.wav"
|
||||
[ 16, 23 ] = wave (0) : "./MITfull/elev70/L70e345a.wav"
|
||||
|
||||
[ 17, 0 ] = wave (0) : "./MITfull/elev80/L80e000a.wav"
|
||||
[ 17, 1 ] = wave (0) : "./MITfull/elev80/L80e030a.wav"
|
||||
[ 17, 2 ] = wave (0) : "./MITfull/elev80/L80e060a.wav"
|
||||
[ 17, 3 ] = wave (0) : "./MITfull/elev80/L80e090a.wav"
|
||||
[ 17, 4 ] = wave (0) : "./MITfull/elev80/L80e120a.wav"
|
||||
[ 17, 5 ] = wave (0) : "./MITfull/elev80/L80e150a.wav"
|
||||
[ 17, 6 ] = wave (0) : "./MITfull/elev80/L80e180a.wav"
|
||||
[ 17, 7 ] = wave (0) : "./MITfull/elev80/L80e210a.wav"
|
||||
[ 17, 8 ] = wave (0) : "./MITfull/elev80/L80e240a.wav"
|
||||
[ 17, 9 ] = wave (0) : "./MITfull/elev80/L80e270a.wav"
|
||||
[ 17, 10 ] = wave (0) : "./MITfull/elev80/L80e300a.wav"
|
||||
[ 17, 11 ] = wave (0) : "./MITfull/elev80/L80e330a.wav"
|
||||
|
||||
[ 18, 0 ] = wave (0) : "./MITfull/elev90/L90e000a.wav"
|
||||
|
||||
+2483
-567
File diff suppressed because it is too large
Load Diff
+10
-5
@@ -125,6 +125,16 @@ static void printALCInfo(ALCdevice *device)
|
||||
{
|
||||
ALCint major, minor;
|
||||
|
||||
if(device)
|
||||
{
|
||||
const ALCchar *devname = NULL;
|
||||
printf("\n");
|
||||
if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
devname = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER);
|
||||
if(checkALCErrors(device) != ALC_NO_ERROR || !devname)
|
||||
devname = alcGetString(device, ALC_DEVICE_SPECIFIER);
|
||||
printf("** Info for device \"%s\" **\n", devname);
|
||||
}
|
||||
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
|
||||
if(checkALCErrors(device) == ALC_NO_ERROR)
|
||||
@@ -276,11 +286,6 @@ int main(int argc, char *argv[])
|
||||
printf("\n!!! Failed to open %s !!!\n\n", ((argc>1) ? argv[1] : "default device"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE)
|
||||
printf("\n** Info for device \"%s\" **\n", alcGetString(device, ALC_ALL_DEVICES_SPECIFIER));
|
||||
else
|
||||
printf("\n** Info for device \"%s\" **\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
|
||||
printALCInfo(device);
|
||||
|
||||
context = alcCreateContext(device, NULL);
|
||||
|
||||
Reference in New Issue
Block a user