diff --git a/love/src/jni/love/Android.mk b/love/src/jni/love/Android.mk index 5cfb6f31..f44bcbc4 100644 --- a/love/src/jni/love/Android.mk +++ b/love/src/jni/love/Android.mk @@ -21,8 +21,8 @@ LOCAL_C_INCLUDES := \ ${LOCAL_PATH}/../libmng-1.0.10/ \ ${LOCAL_PATH}/../lcms2-2.5/include \ ${LOCAL_PATH}/../tiff-3.9.5/libtiff \ - ${LOCAL_PATH}/../openal-soft-1.17.0/include \ - ${LOCAL_PATH}/../openal-soft-1.17.0/OpenAL32/Include \ + ${LOCAL_PATH}/../openal-soft-1.18.2/include \ + ${LOCAL_PATH}/../openal-soft-1.18.2/OpenAL32/Include \ ${LOCAL_PATH}/../freetype2-android/include \ ${LOCAL_PATH}/../freetype2-android/src \ ${LOCAL_PATH}/../physfs-3.0.1/src \ diff --git a/love/src/jni/openal-soft-1.17.0/Alc/ALu.c b/love/src/jni/openal-soft-1.17.0/Alc/ALu.c deleted file mode 100644 index a85e1aa0..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/ALu.c +++ /dev/null @@ -1,1321 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "alMain.h" -#include "alSource.h" -#include "alBuffer.h" -#include "alListener.h" -#include "alAuxEffectSlot.h" -#include "alu.h" -#include "bs2b.h" -#include "hrtf.h" -#include "static_assert.h" - -#include "midi/base.h" - - -static_assert((INT_MAX>>FRACTIONBITS)/MAX_PITCH > BUFFERSIZE, - "MAX_PITCH and/or BUFFERSIZE are too large for FRACTIONBITS!"); - -struct ChanMap { - enum Channel channel; - ALfloat angle; -}; - -/* Cone scalar */ -ALfloat ConeScale = 1.0f; - -/* Localized Z scalar for mono sources */ -ALfloat ZScale = 1.0f; - -extern inline ALfloat minf(ALfloat a, ALfloat b); -extern inline ALfloat maxf(ALfloat a, ALfloat b); -extern inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max); - -extern inline ALdouble mind(ALdouble a, ALdouble b); -extern inline ALdouble maxd(ALdouble a, ALdouble b); -extern inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max); - -extern inline ALuint minu(ALuint a, ALuint b); -extern inline ALuint maxu(ALuint a, ALuint b); -extern inline ALuint clampu(ALuint val, ALuint min, ALuint max); - -extern inline ALint mini(ALint a, ALint b); -extern inline ALint maxi(ALint a, ALint b); -extern inline ALint clampi(ALint val, ALint min, ALint max); - -extern inline ALint64 mini64(ALint64 a, ALint64 b); -extern inline ALint64 maxi64(ALint64 a, ALint64 b); -extern inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max); - -extern inline ALuint64 minu64(ALuint64 a, ALuint64 b); -extern inline ALuint64 maxu64(ALuint64 a, ALuint64 b); -extern inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max); - -extern inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu); -extern inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu); - - -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 lengthsqr = aluDotproduct(inVector, inVector); - if(lengthsqr > 0.0f) - { - ALfloat inv_length = 1.0f/sqrtf(lengthsqr); - inVector[0] *= inv_length; - inVector[1] *= inv_length; - inVector[2] *= inv_length; - } -} - -static inline ALvoid aluMatrixVector(ALfloat *vector, ALfloat w, ALfloat (*restrict matrix)[4]) -{ - ALfloat temp[4] = { - vector[0], vector[1], vector[2], w - }; - - vector[0] = temp[0]*matrix[0][0] + temp[1]*matrix[1][0] + temp[2]*matrix[2][0] + temp[3]*matrix[3][0]; - vector[1] = temp[0]*matrix[0][1] + temp[1]*matrix[1][1] + temp[2]*matrix[2][1] + temp[3]*matrix[3][1]; - vector[2] = temp[0]*matrix[0][2] + temp[1]*matrix[1][2] + temp[2]*matrix[2][2] + temp[3]*matrix[3][2]; -} - - -static ALvoid CalcListenerParams(ALlistener *Listener) -{ - ALfloat N[3], V[3], U[3], P[3]; - - /* AT then UP */ - N[0] = Listener->Forward[0]; - N[1] = Listener->Forward[1]; - N[2] = Listener->Forward[2]; - aluNormalize(N); - V[0] = Listener->Up[0]; - V[1] = Listener->Up[1]; - V[2] = Listener->Up[2]; - aluNormalize(V); - /* Build and normalize right-vector */ - aluCrossproduct(N, V, U); - aluNormalize(U); - - Listener->Params.Matrix[0][0] = U[0]; - Listener->Params.Matrix[0][1] = V[0]; - Listener->Params.Matrix[0][2] = -N[0]; - Listener->Params.Matrix[0][3] = 0.0f; - Listener->Params.Matrix[1][0] = U[1]; - Listener->Params.Matrix[1][1] = V[1]; - Listener->Params.Matrix[1][2] = -N[1]; - Listener->Params.Matrix[1][3] = 0.0f; - Listener->Params.Matrix[2][0] = U[2]; - Listener->Params.Matrix[2][1] = V[2]; - Listener->Params.Matrix[2][2] = -N[2]; - Listener->Params.Matrix[2][3] = 0.0f; - Listener->Params.Matrix[3][0] = 0.0f; - Listener->Params.Matrix[3][1] = 0.0f; - Listener->Params.Matrix[3][2] = 0.0f; - Listener->Params.Matrix[3][3] = 1.0f; - - P[0] = Listener->Position[0]; - P[1] = Listener->Position[1]; - P[2] = Listener->Position[2]; - aluMatrixVector(P, 1.0f, Listener->Params.Matrix); - Listener->Params.Matrix[3][0] = -P[0]; - Listener->Params.Matrix[3][1] = -P[1]; - Listener->Params.Matrix[3][2] = -P[2]; - - Listener->Params.Velocity[0] = Listener->Velocity[0]; - Listener->Params.Velocity[1] = Listener->Velocity[1]; - Listener->Params.Velocity[2] = Listener->Velocity[2]; - aluMatrixVector(Listener->Params.Velocity, 0.0f, Listener->Params.Matrix); -} - -ALvoid CalcNonAttnSourceParams(ALactivesource *src, const ALCcontext *ALContext) -{ - static const struct ChanMap MonoMap[1] = { { FrontCenter, 0.0f } }; - static const struct ChanMap StereoMap[2] = { - { FrontLeft, DEG2RAD(-30.0f) }, - { FrontRight, DEG2RAD( 30.0f) } - }; - static const struct ChanMap StereoWideMap[2] = { - { FrontLeft, DEG2RAD(-90.0f) }, - { FrontRight, DEG2RAD( 90.0f) } - }; - static const struct ChanMap RearMap[2] = { - { BackLeft, DEG2RAD(-150.0f) }, - { BackRight, DEG2RAD( 150.0f) } - }; - static const struct ChanMap QuadMap[4] = { - { FrontLeft, DEG2RAD( -45.0f) }, - { FrontRight, DEG2RAD( 45.0f) }, - { BackLeft, DEG2RAD(-135.0f) }, - { BackRight, DEG2RAD( 135.0f) } - }; - static const struct ChanMap X51Map[6] = { - { FrontLeft, DEG2RAD( -30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackLeft, DEG2RAD(-110.0f) }, - { BackRight, DEG2RAD( 110.0f) } - }; - static const struct ChanMap X61Map[7] = { - { FrontLeft, DEG2RAD(-30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackCenter, DEG2RAD(180.0f) }, - { SideLeft, DEG2RAD(-90.0f) }, - { SideRight, DEG2RAD( 90.0f) } - }; - static const struct ChanMap X71Map[8] = { - { FrontLeft, DEG2RAD( -30.0f) }, - { FrontRight, DEG2RAD( 30.0f) }, - { FrontCenter, DEG2RAD( 0.0f) }, - { LFE, 0.0f }, - { BackLeft, DEG2RAD(-150.0f) }, - { BackRight, DEG2RAD( 150.0f) }, - { SideLeft, DEG2RAD( -90.0f) }, - { SideRight, DEG2RAD( 90.0f) } - }; - - ALCdevice *Device = ALContext->Device; - const ALsource *ALSource = src->Source; - ALfloat SourceVolume,ListenerGain,MinVolume,MaxVolume; - ALbufferlistitem *BufferListItem; - enum FmtChannels Channels; - ALfloat DryGain, DryGainHF, DryGainLF; - ALfloat WetGain[MAX_SENDS]; - ALfloat WetGainHF[MAX_SENDS]; - ALfloat WetGainLF[MAX_SENDS]; - ALint NumSends, Frequency; - const struct ChanMap *chans = NULL; - ALint num_channels = 0; - ALboolean DirectChannels; - ALfloat hwidth = 0.0f; - ALfloat Pitch; - ALint i, j, c; - - /* Get device properties */ - NumSends = Device->NumAuxSends; - Frequency = Device->Frequency; - - /* Get listener properties */ - ListenerGain = ALContext->Listener->Gain; - - /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - DirectChannels = ALSource->DirectChannels; - - src->Direct.OutBuffer = Device->DryBuffer; - for(i = 0;i < NumSends;i++) - { - ALeffectslot *Slot = ALSource->Send[i].Slot; - if(!Slot && i == 0) - Slot = Device->DefaultSlot; - if(!Slot || Slot->EffectType == AL_EFFECT_NULL) - src->Send[i].OutBuffer = NULL; - else - src->Send[i].OutBuffer = Slot->WetBuffer; - } - - /* Calculate the stepping value */ - Channels = FmtMono; - BufferListItem = ATOMIC_LOAD(&ALSource->queue); - while(BufferListItem != NULL) - { - ALbuffer *ALBuffer; - if((ALBuffer=BufferListItem->buffer) != NULL) - { - Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)MAX_PITCH) - src->Step = MAX_PITCH<Step = fastf2i(Pitch*FRACTIONONE); - if(src->Step == 0) - src->Step = 1; - } - - Channels = ALBuffer->FmtChannels; - break; - } - BufferListItem = BufferListItem->next; - } - - /* Calculate gains */ - DryGain = clampf(SourceVolume, MinVolume, MaxVolume); - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF = ALSource->Direct.GainHF; - DryGainLF = ALSource->Direct.GainLF; - for(i = 0;i < NumSends;i++) - { - WetGain[i] = clampf(SourceVolume, MinVolume, MaxVolume); - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] = ALSource->Send[i].GainHF; - WetGainLF[i] = ALSource->Send[i].GainLF; - } - - switch(Channels) - { - case FmtMono: - chans = MonoMap; - num_channels = 1; - break; - - case FmtStereo: - if(!(Device->Flags&DEVICE_WIDE_STEREO)) - { - /* HACK: Place the stereo channels at +/-90 degrees when using non- - * HRTF stereo output. This helps reduce the "monoization" caused - * by them panning towards the center. */ - if(Device->FmtChans == DevFmtStereo && !Device->Hrtf) - chans = StereoWideMap; - else - chans = StereoMap; - } - else - { - chans = StereoWideMap; - hwidth = DEG2RAD(60.0f); - } - num_channels = 2; - break; - - case FmtRear: - chans = RearMap; - num_channels = 2; - break; - - case FmtQuad: - chans = QuadMap; - num_channels = 4; - break; - - case FmtX51: - chans = X51Map; - num_channels = 6; - break; - - case FmtX61: - chans = X61Map; - num_channels = 7; - break; - - case FmtX71: - chans = X71Map; - num_channels = 8; - break; - } - - if(DirectChannels != AL_FALSE) - { - for(c = 0;c < num_channels;c++) - { - MixGains *gains = src->Direct.Mix.Gains[c]; - for(j = 0;j < MaxChannels;j++) - gains[j].Target = 0.0f; - } - - for(c = 0;c < num_channels;c++) - { - MixGains *gains = src->Direct.Mix.Gains[c]; - for(i = 0;i < (ALint)Device->NumChan;i++) - { - enum Channel chan = Device->Speaker2Chan[i]; - if(chan == chans[c].channel) - { - gains[chan].Target = DryGain; - break; - } - } - } - - if(!src->Direct.Moving) - { - for(i = 0;i < num_channels;i++) - { - MixGains *gains = src->Direct.Mix.Gains[i]; - for(j = 0;j < MaxChannels;j++) - { - gains[j].Current = gains[j].Target; - gains[j].Step = 1.0f; - } - } - src->Direct.Counter = 0; - src->Direct.Moving = AL_TRUE; - } - else - { - for(i = 0;i < num_channels;i++) - { - MixGains *gains = src->Direct.Mix.Gains[i]; - for(j = 0;j < MaxChannels;j++) - { - ALfloat cur = maxf(gains[j].Current, FLT_EPSILON); - ALfloat trg = maxf(gains[j].Target, FLT_EPSILON); - if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - gains[j].Step = powf(trg/cur, 1.0f/64.0f); - else - gains[j].Step = 1.0f; - gains[j].Current = cur; - } - } - src->Direct.Counter = 64; - } - - src->IsHrtf = AL_FALSE; - } - else if(Device->Hrtf) - { - for(c = 0;c < num_channels;c++) - { - if(chans[c].channel == LFE) - { - /* Skip LFE */ - src->Direct.Mix.Hrtf.Params[c].Delay[0] = 0; - src->Direct.Mix.Hrtf.Params[c].Delay[1] = 0; - for(i = 0;i < HRIR_LENGTH;i++) - { - src->Direct.Mix.Hrtf.Params[c].Coeffs[i][0] = 0.0f; - src->Direct.Mix.Hrtf.Params[c].Coeffs[i][1] = 0.0f; - } - } - else - { - /* Get the static HRIR coefficients and delays for this - * channel. */ - GetLerpedHrtfCoeffs(Device->Hrtf, - 0.0f, chans[c].angle, 1.0f, DryGain, - src->Direct.Mix.Hrtf.Params[c].Coeffs, - src->Direct.Mix.Hrtf.Params[c].Delay); - } - } - src->Direct.Counter = 0; - src->Direct.Moving = AL_TRUE; - src->Direct.Mix.Hrtf.IrSize = GetHrtfIrSize(Device->Hrtf); - - src->IsHrtf = AL_TRUE; - } - else - { - for(i = 0;i < num_channels;i++) - { - MixGains *gains = src->Direct.Mix.Gains[i]; - for(j = 0;j < MaxChannels;j++) - gains[j].Target = 0.0f; - } - - DryGain *= lerp(1.0f, 1.0f/sqrtf((float)Device->NumChan), hwidth/F_PI); - for(c = 0;c < num_channels;c++) - { - MixGains *gains = src->Direct.Mix.Gains[c]; - ALfloat Target[MaxChannels]; - - /* Special-case LFE */ - if(chans[c].channel == LFE) - { - gains[chans[c].channel].Target = DryGain; - continue; - } - ComputeAngleGains(Device, chans[c].angle, hwidth, DryGain, Target); - for(i = 0;i < MaxChannels;i++) - gains[i].Target = Target[i]; - } - - if(!src->Direct.Moving) - { - for(i = 0;i < num_channels;i++) - { - MixGains *gains = src->Direct.Mix.Gains[i]; - for(j = 0;j < MaxChannels;j++) - { - gains[j].Current = gains[j].Target; - gains[j].Step = 1.0f; - } - } - src->Direct.Counter = 0; - src->Direct.Moving = AL_TRUE; - } - else - { - for(i = 0;i < num_channels;i++) - { - MixGains *gains = src->Direct.Mix.Gains[i]; - for(j = 0;j < MaxChannels;j++) - { - ALfloat trg = maxf(gains[j].Target, FLT_EPSILON); - ALfloat cur = maxf(gains[j].Current, FLT_EPSILON); - if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - gains[j].Step = powf(trg/cur, 1.0f/64.0f); - else - gains[j].Step = 1.0f; - gains[j].Current = cur; - } - } - src->Direct.Counter = 64; - } - - src->IsHrtf = AL_FALSE; - } - for(i = 0;i < NumSends;i++) - { - src->Send[i].Gain.Target = WetGain[i]; - if(!src->Send[i].Moving) - { - src->Send[i].Gain.Current = src->Send[i].Gain.Target; - src->Send[i].Gain.Step = 1.0f; - src->Send[i].Counter = 0; - src->Send[i].Moving = AL_TRUE; - } - else - { - ALfloat cur = maxf(src->Send[i].Gain.Current, FLT_EPSILON); - ALfloat trg = maxf(src->Send[i].Gain.Target, FLT_EPSILON); - if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - src->Send[i].Gain.Step = powf(trg/cur, 1.0f/64.0f); - else - src->Send[i].Gain.Step = 1.0f; - src->Send[i].Gain.Current = cur; - src->Send[i].Counter = 64; - } - } - - { - ALfloat gainhf = maxf(0.01f, DryGainHF); - ALfloat gainlf = maxf(0.01f, DryGainLF); - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; - for(c = 0;c < num_channels;c++) - { - src->Direct.Filters[c].ActiveType = AF_None; - if(gainhf != 1.0f) src->Direct.Filters[c].ActiveType |= AF_LowPass; - if(gainlf != 1.0f) src->Direct.Filters[c].ActiveType |= AF_HighPass; - ALfilterState_setParams( - &src->Direct.Filters[c].LowPass, ALfilterType_HighShelf, gainhf, - hfscale, 0.0f - ); - ALfilterState_setParams( - &src->Direct.Filters[c].HighPass, ALfilterType_LowShelf, gainlf, - lfscale, 0.0f - ); - } - } - for(i = 0;i < NumSends;i++) - { - ALfloat gainhf = maxf(0.01f, WetGainHF[i]); - ALfloat gainlf = maxf(0.01f, WetGainLF[i]); - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; - for(c = 0;c < num_channels;c++) - { - src->Send[i].Filters[c].ActiveType = AF_None; - if(gainhf != 1.0f) src->Send[i].Filters[c].ActiveType |= AF_LowPass; - if(gainlf != 1.0f) src->Send[i].Filters[c].ActiveType |= AF_HighPass; - ALfilterState_setParams( - &src->Send[i].Filters[c].LowPass, ALfilterType_HighShelf, gainhf, - hfscale, 0.0f - ); - ALfilterState_setParams( - &src->Send[i].Filters[c].HighPass, ALfilterType_LowShelf, gainlf, - lfscale, 0.0f - ); - } - } -} - -ALvoid CalcSourceParams(ALactivesource *src, const ALCcontext *ALContext) -{ - ALCdevice *Device = ALContext->Device; - const ALsource *ALSource = src->Source; - ALfloat Velocity[3],Direction[3],Position[3],SourceToListener[3]; - ALfloat InnerAngle,OuterAngle,Angle,Distance,ClampedDist; - ALfloat MinVolume,MaxVolume,MinDist,MaxDist,Rolloff; - ALfloat ConeVolume,ConeHF,SourceVolume,ListenerGain; - ALfloat DopplerFactor, SpeedOfSound; - ALfloat AirAbsorptionFactor; - ALfloat RoomAirAbsorption[MAX_SENDS]; - ALbufferlistitem *BufferListItem; - ALfloat Attenuation; - ALfloat RoomAttenuation[MAX_SENDS]; - ALfloat MetersPerUnit; - ALfloat RoomRolloffBase; - ALfloat RoomRolloff[MAX_SENDS]; - ALfloat DecayDistance[MAX_SENDS]; - ALfloat DryGain; - ALfloat DryGainHF; - ALfloat DryGainLF; - ALboolean DryGainHFAuto; - ALfloat WetGain[MAX_SENDS]; - ALfloat WetGainHF[MAX_SENDS]; - ALfloat WetGainLF[MAX_SENDS]; - ALboolean WetGainAuto; - ALboolean WetGainHFAuto; - ALfloat Pitch; - ALuint Frequency; - ALint NumSends; - ALint i, j; - - DryGainHF = 1.0f; - DryGainLF = 1.0f; - for(i = 0;i < MAX_SENDS;i++) - { - WetGainHF[i] = 1.0f; - WetGainLF[i] = 1.0f; - } - - /* Get context/device properties */ - DopplerFactor = ALContext->DopplerFactor * ALSource->DopplerFactor; - SpeedOfSound = ALContext->SpeedOfSound * ALContext->DopplerVelocity; - NumSends = Device->NumAuxSends; - Frequency = Device->Frequency; - - /* Get listener properties */ - ListenerGain = ALContext->Listener->Gain; - MetersPerUnit = ALContext->Listener->MetersPerUnit; - - /* Get source properties */ - SourceVolume = ALSource->Gain; - MinVolume = ALSource->MinGain; - MaxVolume = ALSource->MaxGain; - Pitch = ALSource->Pitch; - Position[0] = ALSource->Position[0]; - Position[1] = ALSource->Position[1]; - Position[2] = ALSource->Position[2]; - Direction[0] = ALSource->Orientation[0]; - Direction[1] = ALSource->Orientation[1]; - Direction[2] = ALSource->Orientation[2]; - Velocity[0] = ALSource->Velocity[0]; - Velocity[1] = ALSource->Velocity[1]; - Velocity[2] = ALSource->Velocity[2]; - MinDist = ALSource->RefDistance; - MaxDist = ALSource->MaxDistance; - Rolloff = ALSource->RollOffFactor; - InnerAngle = ALSource->InnerAngle; - OuterAngle = ALSource->OuterAngle; - AirAbsorptionFactor = ALSource->AirAbsorptionFactor; - DryGainHFAuto = ALSource->DryGainHFAuto; - WetGainAuto = ALSource->WetGainAuto; - WetGainHFAuto = ALSource->WetGainHFAuto; - RoomRolloffBase = ALSource->RoomRolloffFactor; - - src->Direct.OutBuffer = Device->DryBuffer; - for(i = 0;i < NumSends;i++) - { - ALeffectslot *Slot = ALSource->Send[i].Slot; - - if(!Slot && i == 0) - Slot = Device->DefaultSlot; - if(!Slot || Slot->EffectType == AL_EFFECT_NULL) - { - Slot = NULL; - RoomRolloff[i] = 0.0f; - DecayDistance[i] = 0.0f; - RoomAirAbsorption[i] = 1.0f; - } - else if(Slot->AuxSendAuto) - { - RoomRolloff[i] = RoomRolloffBase; - if(IsReverbEffect(Slot->EffectType)) - { - RoomRolloff[i] += Slot->EffectProps.Reverb.RoomRolloffFactor; - DecayDistance[i] = Slot->EffectProps.Reverb.DecayTime * - SPEEDOFSOUNDMETRESPERSEC; - RoomAirAbsorption[i] = Slot->EffectProps.Reverb.AirAbsorptionGainHF; - } - else - { - DecayDistance[i] = 0.0f; - RoomAirAbsorption[i] = 1.0f; - } - } - else - { - /* If the slot's auxiliary send auto is off, the data sent to the - * effect slot is the same as the dry path, sans filter effects */ - RoomRolloff[i] = Rolloff; - DecayDistance[i] = 0.0f; - RoomAirAbsorption[i] = AIRABSORBGAINHF; - } - - if(!Slot || Slot->EffectType == AL_EFFECT_NULL) - src->Send[i].OutBuffer = NULL; - else - src->Send[i].OutBuffer = Slot->WetBuffer; - } - - /* Transform source to listener space (convert to head relative) */ - if(ALSource->HeadRelative == AL_FALSE) - { - ALfloat (*restrict Matrix)[4] = ALContext->Listener->Params.Matrix; - /* Transform source vectors */ - aluMatrixVector(Position, 1.0f, Matrix); - aluMatrixVector(Direction, 0.0f, Matrix); - aluMatrixVector(Velocity, 0.0f, Matrix); - } - else - { - const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity; - /* Offset the source velocity to be relative of the listener velocity */ - Velocity[0] += ListenerVel[0]; - Velocity[1] += ListenerVel[1]; - Velocity[2] += ListenerVel[2]; - } - - SourceToListener[0] = -Position[0]; - SourceToListener[1] = -Position[1]; - SourceToListener[2] = -Position[2]; - aluNormalize(SourceToListener); - aluNormalize(Direction); - - /* Calculate distance attenuation */ - Distance = sqrtf(aluDotproduct(Position, Position)); - ClampedDist = Distance; - - Attenuation = 1.0f; - for(i = 0;i < NumSends;i++) - RoomAttenuation[i] = 1.0f; - switch(ALContext->SourceDistanceModel ? ALSource->DistanceModel : - ALContext->DistanceModel) - { - case InverseDistanceClamped: - ClampedDist = clampf(ClampedDist, MinDist, MaxDist); - if(MaxDist < MinDist) - break; - /*fall-through*/ - case InverseDistance: - if(MinDist > 0.0f) - { - if((MinDist + (Rolloff * (ClampedDist - MinDist))) > 0.0f) - Attenuation = MinDist / (MinDist + (Rolloff * (ClampedDist - MinDist))); - for(i = 0;i < NumSends;i++) - { - if((MinDist + (RoomRolloff[i] * (ClampedDist - MinDist))) > 0.0f) - RoomAttenuation[i] = MinDist / (MinDist + (RoomRolloff[i] * (ClampedDist - MinDist))); - } - } - break; - - case LinearDistanceClamped: - ClampedDist = clampf(ClampedDist, MinDist, MaxDist); - if(MaxDist < MinDist) - break; - /*fall-through*/ - case LinearDistance: - if(MaxDist != MinDist) - { - Attenuation = 1.0f - (Rolloff*(ClampedDist-MinDist)/(MaxDist - MinDist)); - Attenuation = maxf(Attenuation, 0.0f); - for(i = 0;i < NumSends;i++) - { - RoomAttenuation[i] = 1.0f - (RoomRolloff[i]*(ClampedDist-MinDist)/(MaxDist - MinDist)); - RoomAttenuation[i] = maxf(RoomAttenuation[i], 0.0f); - } - } - break; - - case ExponentDistanceClamped: - ClampedDist = clampf(ClampedDist, MinDist, MaxDist); - if(MaxDist < MinDist) - break; - /*fall-through*/ - case ExponentDistance: - if(ClampedDist > 0.0f && MinDist > 0.0f) - { - Attenuation = powf(ClampedDist/MinDist, -Rolloff); - for(i = 0;i < NumSends;i++) - RoomAttenuation[i] = powf(ClampedDist/MinDist, -RoomRolloff[i]); - } - break; - - case DisableDistance: - ClampedDist = MinDist; - break; - } - - /* Source Gain + Attenuation */ - DryGain = SourceVolume * Attenuation; - for(i = 0;i < NumSends;i++) - WetGain[i] = SourceVolume * RoomAttenuation[i]; - - /* Distance-based air absorption */ - if(AirAbsorptionFactor > 0.0f && ClampedDist > MinDist) - { - ALfloat meters = maxf(ClampedDist-MinDist, 0.0f) * MetersPerUnit; - DryGainHF *= powf(AIRABSORBGAINHF, AirAbsorptionFactor*meters); - for(i = 0;i < NumSends;i++) - WetGainHF[i] *= powf(RoomAirAbsorption[i], AirAbsorptionFactor*meters); - } - - if(WetGainAuto) - { - ALfloat ApparentDist = 1.0f/maxf(Attenuation, 0.00001f) - 1.0f; - - /* Apply a decay-time transformation to the wet path, based on the - * attenuation of the dry path. - * - * Using the apparent distance, based on the distance attenuation, the - * initial decay of the reverb effect is calculated and applied to the - * wet path. - */ - for(i = 0;i < NumSends;i++) - { - if(DecayDistance[i] > 0.0f) - WetGain[i] *= powf(0.001f/*-60dB*/, ApparentDist/DecayDistance[i]); - } - } - - /* Calculate directional soundcones */ - Angle = RAD2DEG(acosf(aluDotproduct(Direction,SourceToListener)) * ConeScale) * 2.0f; - if(Angle > InnerAngle && Angle <= OuterAngle) - { - ALfloat scale = (Angle-InnerAngle) / (OuterAngle-InnerAngle); - ConeVolume = lerp(1.0f, ALSource->OuterGain, scale); - ConeHF = lerp(1.0f, ALSource->OuterGainHF, scale); - } - else if(Angle > OuterAngle) - { - ConeVolume = ALSource->OuterGain; - ConeHF = ALSource->OuterGainHF; - } - else - { - ConeVolume = 1.0f; - ConeHF = 1.0f; - } - - DryGain *= ConeVolume; - if(WetGainAuto) - { - for(i = 0;i < NumSends;i++) - WetGain[i] *= ConeVolume; - } - if(DryGainHFAuto) - DryGainHF *= ConeHF; - if(WetGainHFAuto) - { - for(i = 0;i < NumSends;i++) - WetGainHF[i] *= ConeHF; - } - - /* Clamp to Min/Max Gain */ - DryGain = clampf(DryGain, MinVolume, MaxVolume); - for(i = 0;i < NumSends;i++) - WetGain[i] = clampf(WetGain[i], MinVolume, MaxVolume); - - /* Apply gain and frequency filters */ - DryGain *= ALSource->Direct.Gain * ListenerGain; - DryGainHF *= ALSource->Direct.GainHF; - DryGainLF *= ALSource->Direct.GainLF; - for(i = 0;i < NumSends;i++) - { - WetGain[i] *= ALSource->Send[i].Gain * ListenerGain; - WetGainHF[i] *= ALSource->Send[i].GainHF; - WetGainLF[i] *= ALSource->Send[i].GainLF; - } - - /* Calculate velocity-based doppler effect */ - if(DopplerFactor > 0.0f) - { - const ALfloat *ListenerVel = ALContext->Listener->Params.Velocity; - ALfloat VSS, VLS; - - if(SpeedOfSound < 1.0f) - { - DopplerFactor *= 1.0f/SpeedOfSound; - SpeedOfSound = 1.0f; - } - - VSS = aluDotproduct(Velocity, SourceToListener) * DopplerFactor; - VLS = aluDotproduct(ListenerVel, SourceToListener) * DopplerFactor; - - Pitch *= clampf(SpeedOfSound-VLS, 1.0f, SpeedOfSound*2.0f - 1.0f) / - clampf(SpeedOfSound-VSS, 1.0f, SpeedOfSound*2.0f - 1.0f); - } - - BufferListItem = ATOMIC_LOAD(&ALSource->queue); - while(BufferListItem != NULL) - { - ALbuffer *ALBuffer; - if((ALBuffer=BufferListItem->buffer) != NULL) - { - /* Calculate fixed-point stepping value, based on the pitch, buffer - * frequency, and output frequency. */ - Pitch = Pitch * ALBuffer->Frequency / Frequency; - if(Pitch > (ALfloat)MAX_PITCH) - src->Step = MAX_PITCH<Step = fastf2i(Pitch*FRACTIONONE); - if(src->Step == 0) - src->Step = 1; - } - - break; - } - BufferListItem = BufferListItem->next; - } - - if(Device->Hrtf) - { - /* Use a binaural HRTF algorithm for stereo headphone playback */ - ALfloat delta, ev = 0.0f, az = 0.0f; - ALfloat radius = ALSource->Radius; - ALfloat dirfact = 1.0f; - - if(Distance > FLT_EPSILON) - { - ALfloat invlen = 1.0f/Distance; - Position[0] *= invlen; - Position[1] *= invlen; - Position[2] *= invlen; - - /* Calculate elevation and azimuth only when the source is not at - * the listener. This prevents +0 and -0 Z from producing - * inconsistent panning. Also, clamp Y in case FP precision errors - * cause it to land outside of -1..+1. */ - ev = asinf(clampf(Position[1], -1.0f, 1.0f)); - az = atan2f(Position[0], -Position[2]*ZScale); - } - if(radius > Distance) - dirfact *= Distance / radius; - - /* Check to see if the HRIR is already moving. */ - if(src->Direct.Moving) - { - /* Calculate the normalized HRTF transition factor (delta). */ - delta = CalcHrtfDelta(src->Direct.Mix.Hrtf.Gain, DryGain, - src->Direct.Mix.Hrtf.Dir, Position); - /* If the delta is large enough, get the moving HRIR target - * coefficients, target delays, steppping values, and counter. */ - if(delta > 0.001f) - { - ALuint counter = GetMovingHrtfCoeffs(Device->Hrtf, - ev, az, dirfact, DryGain, delta, src->Direct.Counter, - src->Direct.Mix.Hrtf.Params[0].Coeffs, src->Direct.Mix.Hrtf.Params[0].Delay, - src->Direct.Mix.Hrtf.Params[0].CoeffStep, src->Direct.Mix.Hrtf.Params[0].DelayStep - ); - src->Direct.Counter = counter; - src->Direct.Mix.Hrtf.Gain = DryGain; - src->Direct.Mix.Hrtf.Dir[0] = Position[0]; - src->Direct.Mix.Hrtf.Dir[1] = Position[1]; - src->Direct.Mix.Hrtf.Dir[2] = Position[2]; - } - } - else - { - /* Get the initial (static) HRIR coefficients and delays. */ - GetLerpedHrtfCoeffs(Device->Hrtf, ev, az, dirfact, DryGain, - src->Direct.Mix.Hrtf.Params[0].Coeffs, - src->Direct.Mix.Hrtf.Params[0].Delay); - src->Direct.Counter = 0; - src->Direct.Moving = AL_TRUE; - src->Direct.Mix.Hrtf.Gain = DryGain; - src->Direct.Mix.Hrtf.Dir[0] = Position[0]; - src->Direct.Mix.Hrtf.Dir[1] = Position[1]; - src->Direct.Mix.Hrtf.Dir[2] = Position[2]; - } - src->Direct.Mix.Hrtf.IrSize = GetHrtfIrSize(Device->Hrtf); - - src->IsHrtf = AL_TRUE; - } - else - { - MixGains *gains = src->Direct.Mix.Gains[0]; - ALfloat DirGain = 0.0f; - ALfloat AmbientGain; - - for(j = 0;j < MaxChannels;j++) - gains[j].Target = 0.0f; - - /* Normalize the length, and compute panned gains. */ - if(Distance > FLT_EPSILON) - { - ALfloat radius = ALSource->Radius; - ALfloat Target[MaxChannels]; - ALfloat invlen = 1.0f/maxf(Distance, radius); - Position[0] *= invlen; - Position[1] *= invlen; - Position[2] *= invlen; - - DirGain = sqrtf(Position[0]*Position[0] + Position[2]*Position[2]); - ComputeAngleGains(Device, atan2f(Position[0], -Position[2]*ZScale), 0.0f, - DryGain*DirGain, Target); - for(j = 0;j < MaxChannels;j++) - gains[j].Target = Target[j]; - } - - /* Adjustment for vertical offsets. Not the greatest, but simple - * enough. */ - AmbientGain = DryGain * sqrtf(1.0f/Device->NumChan) * (1.0f-DirGain); - for(i = 0;i < (ALint)Device->NumChan;i++) - { - enum Channel chan = Device->Speaker2Chan[i]; - gains[chan].Target = maxf(gains[chan].Target, AmbientGain); - } - - if(!src->Direct.Moving) - { - for(j = 0;j < MaxChannels;j++) - { - gains[j].Current = gains[j].Target; - gains[j].Step = 1.0f; - } - src->Direct.Counter = 0; - src->Direct.Moving = AL_TRUE; - } - else - { - for(j = 0;j < MaxChannels;j++) - { - ALfloat cur = maxf(gains[j].Current, FLT_EPSILON); - ALfloat trg = maxf(gains[j].Target, FLT_EPSILON); - if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - gains[j].Step = powf(trg/cur, 1.0f/64.0f); - else - gains[j].Step = 1.0f; - gains[j].Current = cur; - } - src->Direct.Counter = 64; - } - - src->IsHrtf = AL_FALSE; - } - for(i = 0;i < NumSends;i++) - { - src->Send[i].Gain.Target = WetGain[i]; - if(!src->Send[i].Moving) - { - src->Send[i].Gain.Current = src->Send[i].Gain.Target; - src->Send[i].Gain.Step = 1.0f; - src->Send[i].Counter = 0; - src->Send[i].Moving = AL_TRUE; - } - else - { - ALfloat cur = maxf(src->Send[i].Gain.Current, FLT_EPSILON); - ALfloat trg = maxf(src->Send[i].Gain.Target, FLT_EPSILON); - if(fabs(trg - cur) >= GAIN_SILENCE_THRESHOLD) - src->Send[i].Gain.Step = powf(trg/cur, 1.0f/64.0f); - else - src->Send[i].Gain.Step = 1.0f; - src->Send[i].Gain.Current = cur; - src->Send[i].Counter = 64; - } - } - - { - ALfloat gainhf = maxf(0.01f, DryGainHF); - ALfloat gainlf = maxf(0.01f, DryGainLF); - ALfloat hfscale = ALSource->Direct.HFReference / Frequency; - ALfloat lfscale = ALSource->Direct.LFReference / Frequency; - src->Direct.Filters[0].ActiveType = AF_None; - if(gainhf != 1.0f) src->Direct.Filters[0].ActiveType |= AF_LowPass; - if(gainlf != 1.0f) src->Direct.Filters[0].ActiveType |= AF_HighPass; - ALfilterState_setParams( - &src->Direct.Filters[0].LowPass, ALfilterType_HighShelf, gainhf, - hfscale, 0.0f - ); - ALfilterState_setParams( - &src->Direct.Filters[0].HighPass, ALfilterType_LowShelf, gainlf, - lfscale, 0.0f - ); - } - for(i = 0;i < NumSends;i++) - { - ALfloat gainhf = maxf(0.01f, WetGainHF[i]); - ALfloat gainlf = maxf(0.01f, WetGainLF[i]); - ALfloat hfscale = ALSource->Send[i].HFReference / Frequency; - ALfloat lfscale = ALSource->Send[i].LFReference / Frequency; - src->Send[i].Filters[0].ActiveType = AF_None; - if(gainhf != 1.0f) src->Send[i].Filters[0].ActiveType |= AF_LowPass; - if(gainlf != 1.0f) src->Send[i].Filters[0].ActiveType |= AF_HighPass; - ALfilterState_setParams( - &src->Send[i].Filters[0].LowPass, ALfilterType_HighShelf, gainhf, - hfscale, 0.0f - ); - ALfilterState_setParams( - &src->Send[i].Filters[0].HighPass, ALfilterType_LowShelf, gainlf, - lfscale, 0.0f - ); - } -} - - -static inline ALint aluF2I25(ALfloat val) -{ - /* Clamp the value between -1 and +1. This handles that with only a single branch. */ - if(fabsf(val) > 1.0f) - val = (ALfloat)((0.0f < val) - (val < 0.0f)); - /* Convert to a signed integer, between -16777215 and +16777215. */ - return fastf2i(val*16777215.0f); -} - -static inline ALfloat aluF2F(ALfloat val) -{ return val; } -static inline ALint aluF2I(ALfloat val) -{ return aluF2I25(val)<<7; } -static inline ALuint aluF2UI(ALfloat val) -{ return aluF2I(val)+2147483648u; } -static inline ALshort aluF2S(ALfloat val) -{ return aluF2I25(val)>>9; } -static inline ALushort aluF2US(ALfloat val) -{ return aluF2S(val)+32768; } -static inline ALbyte aluF2B(ALfloat val) -{ return aluF2I25(val)>>17; } -static inline ALubyte aluF2UB(ALfloat val) -{ return aluF2B(val)+128; } - -#define DECL_TEMPLATE(T, func) \ -static void Write_##T(ALCdevice *device, ALvoid **buffer, ALuint SamplesToDo) \ -{ \ - ALfloat (*restrict DryBuffer)[BUFFERSIZE] = device->DryBuffer; \ - const ALuint numchans = ChannelsFromDevFmt(device->FmtChans); \ - const ALuint *offsets = device->ChannelOffsets; \ - ALuint i, j; \ - \ - for(j = 0;j < MaxChannels;j++) \ - { \ - T *restrict out; \ - \ - if(offsets[j] == INVALID_OFFSET) \ - continue; \ - \ - out = (T*)(*buffer) + offsets[j]; \ - for(i = 0;i < SamplesToDo;i++) \ - out[i*numchans] = func(DryBuffer[j][i]); \ - } \ - *buffer = (char*)(*buffer) + SamplesToDo*numchans*sizeof(T); \ -} - -DECL_TEMPLATE(ALfloat, aluF2F) -DECL_TEMPLATE(ALuint, aluF2UI) -DECL_TEMPLATE(ALint, aluF2I) -DECL_TEMPLATE(ALushort, aluF2US) -DECL_TEMPLATE(ALshort, aluF2S) -DECL_TEMPLATE(ALubyte, aluF2UB) -DECL_TEMPLATE(ALbyte, aluF2B) - -#undef DECL_TEMPLATE - - -ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size) -{ - ALuint SamplesToDo; - ALeffectslot **slot, **slot_end; - ALactivesource **src, **src_end; - ALCcontext *ctx; - FPUCtl oldMode; - ALuint i, c; - - SetMixerFPUMode(&oldMode); - - while(size > 0) - { - IncrementRef(&device->MixCount); - - SamplesToDo = minu(size, BUFFERSIZE); - for(c = 0;c < MaxChannels;c++) - memset(device->DryBuffer[c], 0, SamplesToDo*sizeof(ALfloat)); - - ALCdevice_Lock(device); - V(device->Synth,process)(SamplesToDo, device->DryBuffer); - - ctx = ATOMIC_LOAD(&device->ContextList); - while(ctx) - { - ALenum DeferUpdates = ctx->DeferUpdates; - ALenum UpdateSources = AL_FALSE; - - if(!DeferUpdates) - UpdateSources = ATOMIC_EXCHANGE(ALenum, &ctx->UpdateSources, AL_FALSE); - - if(UpdateSources) - CalcListenerParams(ctx->Listener); - - /* source processing */ - src = ctx->ActiveSources; - src_end = src + ctx->ActiveSourceCount; - while(src != src_end) - { - ALsource *source = (*src)->Source; - - if(source->state != AL_PLAYING && source->state != AL_PAUSED) - { - ALactivesource *temp = *(--src_end); - *src_end = *src; - *src = temp; - --(ctx->ActiveSourceCount); - continue; - } - - if(!DeferUpdates && (ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || - UpdateSources)) - (*src)->Update(*src, ctx); - - if(source->state != AL_PAUSED) - MixSource(*src, device, SamplesToDo); - src++; - } - - /* effect slot processing */ - slot = VECTOR_ITER_BEGIN(ctx->ActiveAuxSlots); - slot_end = VECTOR_ITER_END(ctx->ActiveAuxSlots); - while(slot != slot_end) - { - if(!DeferUpdates && ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE)) - V((*slot)->EffectState,update)(device, *slot); - - V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], - device->DryBuffer); - - for(i = 0;i < SamplesToDo;i++) - (*slot)->WetBuffer[0][i] = 0.0f; - - slot++; - } - - ctx = ctx->next; - } - - slot = &device->DefaultSlot; - if(*slot != NULL) - { - if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE)) - V((*slot)->EffectState,update)(device, *slot); - - V((*slot)->EffectState,process)(SamplesToDo, (*slot)->WetBuffer[0], - device->DryBuffer); - - for(i = 0;i < SamplesToDo;i++) - (*slot)->WetBuffer[0][i] = 0.0f; - } - - /* Increment the clock time. Every second's worth of samples is - * converted and added to clock base so that large sample counts don't - * overflow during conversion. This also guarantees an exact, stable - * conversion. */ - device->SamplesDone += SamplesToDo; - device->ClockBase += (device->SamplesDone/device->Frequency) * DEVICE_CLOCK_RES; - device->SamplesDone %= device->Frequency; - ALCdevice_Unlock(device); - - if(device->Bs2b) - { - /* Apply binaural/crossfeed filter */ - for(i = 0;i < SamplesToDo;i++) - { - float samples[2]; - samples[0] = device->DryBuffer[FrontLeft][i]; - samples[1] = device->DryBuffer[FrontRight][i]; - bs2b_cross_feed(device->Bs2b, samples); - device->DryBuffer[FrontLeft][i] = samples[0]; - device->DryBuffer[FrontRight][i] = samples[1]; - } - } - - if(buffer) - { - switch(device->FmtType) - { - case DevFmtByte: - Write_ALbyte(device, &buffer, SamplesToDo); - break; - case DevFmtUByte: - Write_ALubyte(device, &buffer, SamplesToDo); - break; - case DevFmtShort: - Write_ALshort(device, &buffer, SamplesToDo); - break; - case DevFmtUShort: - Write_ALushort(device, &buffer, SamplesToDo); - break; - case DevFmtInt: - Write_ALint(device, &buffer, SamplesToDo); - break; - case DevFmtUInt: - Write_ALuint(device, &buffer, SamplesToDo); - break; - case DevFmtFloat: - Write_ALfloat(device, &buffer, SamplesToDo); - break; - } - } - - size -= SamplesToDo; - IncrementRef(&device->MixCount); - } - - RestoreFPUMode(&oldMode); -} - - -ALvoid aluHandleDisconnect(ALCdevice *device) -{ - ALCcontext *Context; - - device->Connected = ALC_FALSE; - - Context = ATOMIC_LOAD(&device->ContextList); - while(Context) - { - ALactivesource **src, **src_end; - - src = Context->ActiveSources; - src_end = src + Context->ActiveSourceCount; - while(src != src_end) - { - ALsource *source = (*src)->Source; - if(source->state == AL_PLAYING) - { - source->state = AL_STOPPED; - ATOMIC_STORE(&source->current_buffer, NULL); - source->position = 0; - source->position_fraction = 0; - } - src++; - } - Context->ActiveSourceCount = 0; - - Context = Context->next; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/alcRing.c b/love/src/jni/openal-soft-1.17.0/Alc/alcRing.c deleted file mode 100644 index 9b5d8214..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/alcRing.c +++ /dev/null @@ -1,129 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "threads.h" -#include "compat.h" - - -struct RingBuffer { - ALubyte *mem; - - ALsizei frame_size; - ALsizei length; - ALint read_pos; - ALint write_pos; - - almtx_t mtx; -}; - - -RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length) -{ - RingBuffer *ring = calloc(1, sizeof(*ring) + ((length+1) * frame_size)); - if(ring) - { - ring->mem = (ALubyte*)(ring+1); - - ring->frame_size = frame_size; - ring->length = length+1; - ring->read_pos = 0; - ring->write_pos = 0; - - almtx_init(&ring->mtx, almtx_plain); - } - return ring; -} - -void DestroyRingBuffer(RingBuffer *ring) -{ - if(ring) - { - almtx_destroy(&ring->mtx); - free(ring); - } -} - -ALsizei RingBufferSize(RingBuffer *ring) -{ - ALsizei s; - - almtx_lock(&ring->mtx); - s = (ring->write_pos-ring->read_pos+ring->length) % ring->length; - almtx_unlock(&ring->mtx); - - return s; -} - -void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len) -{ - int remain; - - almtx_lock(&ring->mtx); - - remain = (ring->read_pos-ring->write_pos-1+ring->length) % ring->length; - if(remain < len) len = remain; - - if(len > 0) - { - remain = ring->length - ring->write_pos; - if(remain < len) - { - memcpy(ring->mem+(ring->write_pos*ring->frame_size), data, - remain*ring->frame_size); - memcpy(ring->mem, data+(remain*ring->frame_size), - (len-remain)*ring->frame_size); - } - else - memcpy(ring->mem+(ring->write_pos*ring->frame_size), data, - len*ring->frame_size); - - ring->write_pos += len; - ring->write_pos %= ring->length; - } - - almtx_unlock(&ring->mtx); -} - -void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len) -{ - int remain; - - almtx_lock(&ring->mtx); - - remain = ring->length - ring->read_pos; - if(remain < len) - { - memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), remain*ring->frame_size); - memcpy(data+(remain*ring->frame_size), ring->mem, (len-remain)*ring->frame_size); - } - else - memcpy(data, ring->mem+(ring->read_pos*ring->frame_size), len*ring->frame_size); - - ring->read_pos += len; - ring->read_pos %= ring->length; - - almtx_unlock(&ring->mtx); -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/alstring.h b/love/src/jni/openal-soft-1.17.0/Alc/alstring.h deleted file mode 100644 index 32f4280a..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/alstring.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef ALSTRING_H -#define ALSTRING_H - -#include - -#include "vector.h" - - -typedef char al_string_char_type; -TYPEDEF_VECTOR(al_string_char_type, al_string) - -inline void al_string_deinit(al_string *str) -{ VECTOR_DEINIT(*str); } -#define AL_STRING_INIT(_x) do { (_x) = (al_string)NULL; } while(0) -#define AL_STRING_INIT_STATIC() ((al_string)NULL) -#define AL_STRING_DEINIT(_x) al_string_deinit(&(_x)) - -inline ALsizei al_string_length(const_al_string str) -{ return VECTOR_SIZE(str); } - -inline ALboolean al_string_empty(const_al_string str) -{ return al_string_length(str) == 0; } - -inline const al_string_char_type *al_string_get_cstr(const_al_string str) -{ return str ? &VECTOR_FRONT(str) : ""; } - -void al_string_clear(al_string *str); - -int al_string_cmp(const_al_string str1, const_al_string str2); -int al_string_cmp_cstr(const_al_string str1, const al_string_char_type *str2); - -void al_string_copy(al_string *str, const_al_string from); -void al_string_copy_cstr(al_string *str, const al_string_char_type *from); - -void al_string_append_char(al_string *str, const al_string_char_type c); -void al_string_append_cstr(al_string *str, const al_string_char_type *from); -void al_string_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to); - -#ifdef _WIN32 -#include -/* Windows-only methods to deal with WideChar strings. */ -void al_string_copy_wcstr(al_string *str, const wchar_t *from); -#endif - -#endif /* ALSTRING_H */ diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/base.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/base.c deleted file mode 100644 index 37e4ccc9..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/base.c +++ /dev/null @@ -1,232 +0,0 @@ - -#include "config.h" - -#include - -#include "alMain.h" - -#include "backends/base.h" - - -/* Base ALCbackend method implementations. */ -void ALCbackend_Construct(ALCbackend *self, ALCdevice *device) -{ - int ret; - self->mDevice = device; - ret = almtx_init(&self->mMutex, almtx_recursive); - assert(ret == althrd_success); -} - -void ALCbackend_Destruct(ALCbackend *self) -{ - almtx_destroy(&self->mMutex); -} - -ALCboolean ALCbackend_reset(ALCbackend* UNUSED(self)) -{ - return ALC_FALSE; -} - -ALCenum ALCbackend_captureSamples(ALCbackend* UNUSED(self), void* UNUSED(buffer), ALCuint UNUSED(samples)) -{ - return ALC_INVALID_DEVICE; -} - -ALCuint ALCbackend_availableSamples(ALCbackend* UNUSED(self)) -{ - return 0; -} - -ALint64 ALCbackend_getLatency(ALCbackend* UNUSED(self)) -{ - return 0; -} - -void ALCbackend_lock(ALCbackend *self) -{ - int ret = almtx_lock(&self->mMutex); - assert(ret == althrd_success); -} - -void ALCbackend_unlock(ALCbackend *self) -{ - int ret = almtx_unlock(&self->mMutex); - assert(ret == althrd_success); -} - - -/* Base ALCbackendFactory method implementations. */ -void ALCbackendFactory_deinit(ALCbackendFactory* UNUSED(self)) -{ -} - - -/* Wrappers to use an old-style backend with the new interface. */ -typedef struct PlaybackWrapper { - DERIVE_FROM_TYPE(ALCbackend); - - const BackendFuncs *Funcs; -} PlaybackWrapper; - -static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device, const BackendFuncs *funcs); -static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, Destruct) -static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name); -static void PlaybackWrapper_close(PlaybackWrapper *self); -static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self); -static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self); -static void PlaybackWrapper_stop(PlaybackWrapper *self); -static DECLARE_FORWARD2(PlaybackWrapper, ALCbackend, ALCenum, captureSamples, void*, ALCuint) -static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, ALCuint, availableSamples) -static ALint64 PlaybackWrapper_getLatency(PlaybackWrapper *self); -static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, lock) -static DECLARE_FORWARD(PlaybackWrapper, ALCbackend, void, unlock) -DECLARE_DEFAULT_ALLOCATORS(PlaybackWrapper) -DEFINE_ALCBACKEND_VTABLE(PlaybackWrapper); - -static void PlaybackWrapper_Construct(PlaybackWrapper *self, ALCdevice *device, const BackendFuncs *funcs) -{ - ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); - SET_VTABLE2(PlaybackWrapper, ALCbackend, self); - - self->Funcs = funcs; -} - -static ALCenum PlaybackWrapper_open(PlaybackWrapper *self, const ALCchar *name) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->OpenPlayback(device, name); -} - -static void PlaybackWrapper_close(PlaybackWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - self->Funcs->ClosePlayback(device); -} - -static ALCboolean PlaybackWrapper_reset(PlaybackWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->ResetPlayback(device); -} - -static ALCboolean PlaybackWrapper_start(PlaybackWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->StartPlayback(device); -} - -static void PlaybackWrapper_stop(PlaybackWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - self->Funcs->StopPlayback(device); -} - -static ALint64 PlaybackWrapper_getLatency(PlaybackWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->GetLatency(device); -} - - -typedef struct CaptureWrapper { - DERIVE_FROM_TYPE(ALCbackend); - - const BackendFuncs *Funcs; -} CaptureWrapper; - -static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device, const BackendFuncs *funcs); -static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, Destruct) -static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name); -static void CaptureWrapper_close(CaptureWrapper *self); -static DECLARE_FORWARD(CaptureWrapper, ALCbackend, ALCboolean, reset) -static ALCboolean CaptureWrapper_start(CaptureWrapper *self); -static void CaptureWrapper_stop(CaptureWrapper *self); -static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples); -static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self); -static ALint64 CaptureWrapper_getLatency(CaptureWrapper *self); -static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, lock) -static DECLARE_FORWARD(CaptureWrapper, ALCbackend, void, unlock) -DECLARE_DEFAULT_ALLOCATORS(CaptureWrapper) -DEFINE_ALCBACKEND_VTABLE(CaptureWrapper); - - -static void CaptureWrapper_Construct(CaptureWrapper *self, ALCdevice *device, const BackendFuncs *funcs) -{ - ALCbackend_Construct(STATIC_CAST(ALCbackend, self), device); - SET_VTABLE2(CaptureWrapper, ALCbackend, self); - - self->Funcs = funcs; -} - -static ALCenum CaptureWrapper_open(CaptureWrapper *self, const ALCchar *name) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->OpenCapture(device, name); -} - -static void CaptureWrapper_close(CaptureWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - self->Funcs->CloseCapture(device); -} - -static ALCboolean CaptureWrapper_start(CaptureWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - self->Funcs->StartCapture(device); - return ALC_TRUE; -} - -static void CaptureWrapper_stop(CaptureWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - self->Funcs->StopCapture(device); -} - -static ALCenum CaptureWrapper_captureSamples(CaptureWrapper *self, void *buffer, ALCuint samples) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->CaptureSamples(device, buffer, samples); -} - -static ALCuint CaptureWrapper_availableSamples(CaptureWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->AvailableSamples(device); -} - -static ALint64 CaptureWrapper_getLatency(CaptureWrapper *self) -{ - ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; - return self->Funcs->GetLatency(device); -} - - -ALCbackend *create_backend_wrapper(ALCdevice *device, const BackendFuncs *funcs, ALCbackend_Type type) -{ - if(type == ALCbackend_Playback) - { - PlaybackWrapper *backend; - - backend = PlaybackWrapper_New(sizeof(*backend)); - if(!backend) return NULL; - - PlaybackWrapper_Construct(backend, device, funcs); - - return STATIC_CAST(ALCbackend, backend); - } - - if(type == ALCbackend_Capture) - { - CaptureWrapper *backend; - - backend = CaptureWrapper_New(sizeof(*backend)); - if(!backend) return NULL; - - CaptureWrapper_Construct(backend, device, funcs); - - return STATIC_CAST(ALCbackend, backend); - } - - return NULL; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/opensl.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/opensl.c deleted file mode 100644 index 220e6e5c..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/opensl.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This is an OpenAL backend for Android using the native audio APIs based on - * OpenSL ES 1.0.1. It is based on source code for the native-audio sample app - * bundled with NDK. - */ - -#include "config.h" - -#include - -#include "alMain.h" -#include "alu.h" - - -#include -#include - -/* Helper macros */ -#define VCALL(obj, func) ((*(obj))->func((obj), EXTRACT_VCALL_ARGS -#define VCALL0(obj, func) ((*(obj))->func((obj) EXTRACT_VCALL_ARGS - - -typedef struct { - /* engine interfaces */ - SLObjectItf engineObject; - SLEngineItf engine; - - /* output mix interfaces */ - SLObjectItf outputMix; - - /* buffer queue player interfaces */ - SLObjectItf bufferQueueObject; - - void *buffer; - ALuint bufferSize; - ALuint curBuffer; - - ALuint frameSize; -} osl_data; - - -static const ALCchar opensl_device[] = "OpenSL"; - - -static SLuint32 GetChannelMask(enum DevFmtChannels chans) -{ - switch(chans) - { - case DevFmtMono: return SL_SPEAKER_FRONT_CENTER; - case DevFmtStereo: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT; - case DevFmtQuad: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT; - case DevFmtX51: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT; - case DevFmtX61: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| - SL_SPEAKER_BACK_CENTER| - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; - case DevFmtX71: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| - SL_SPEAKER_BACK_LEFT|SL_SPEAKER_BACK_RIGHT| - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; - case DevFmtX51Side: return SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT| - SL_SPEAKER_FRONT_CENTER|SL_SPEAKER_LOW_FREQUENCY| - SL_SPEAKER_SIDE_LEFT|SL_SPEAKER_SIDE_RIGHT; - } - return 0; -} - -static const char *res_str(SLresult result) -{ - switch(result) - { - case SL_RESULT_SUCCESS: return "Success"; - case SL_RESULT_PRECONDITIONS_VIOLATED: return "Preconditions violated"; - case SL_RESULT_PARAMETER_INVALID: return "Parameter invalid"; - case SL_RESULT_MEMORY_FAILURE: return "Memory failure"; - case SL_RESULT_RESOURCE_ERROR: return "Resource error"; - case SL_RESULT_RESOURCE_LOST: return "Resource lost"; - case SL_RESULT_IO_ERROR: return "I/O error"; - case SL_RESULT_BUFFER_INSUFFICIENT: return "Buffer insufficient"; - case SL_RESULT_CONTENT_CORRUPTED: return "Content corrupted"; - case SL_RESULT_CONTENT_UNSUPPORTED: return "Content unsupported"; - case SL_RESULT_CONTENT_NOT_FOUND: return "Content not found"; - case SL_RESULT_PERMISSION_DENIED: return "Permission denied"; - case SL_RESULT_FEATURE_UNSUPPORTED: return "Feature unsupported"; - case SL_RESULT_INTERNAL_ERROR: return "Internal error"; - case SL_RESULT_UNKNOWN_ERROR: return "Unknown error"; - case SL_RESULT_OPERATION_ABORTED: return "Operation aborted"; - case SL_RESULT_CONTROL_LOST: return "Control lost"; -#ifdef SL_RESULT_READONLY - case SL_RESULT_READONLY: return "ReadOnly"; -#endif -#ifdef SL_RESULT_ENGINEOPTION_UNSUPPORTED - case SL_RESULT_ENGINEOPTION_UNSUPPORTED: return "Engine option unsupported"; -#endif -#ifdef SL_RESULT_SOURCE_SINK_INCOMPATIBLE - case SL_RESULT_SOURCE_SINK_INCOMPATIBLE: return "Source/Sink incompatible"; -#endif - } - return "Unknown error code"; -} - -#define PRINTERR(x, s) do { \ - if((x) != SL_RESULT_SUCCESS) \ - ERR("%s: %s\n", (s), res_str((x))); \ -} while(0) - -/* this callback handler is called every time a buffer finishes playing */ -static void opensl_callback(SLAndroidSimpleBufferQueueItf bq, void *context) -{ - ALCdevice *Device = context; - osl_data *data = Device->ExtraData; - ALvoid *buf; - SLresult result; - - buf = (ALbyte*)data->buffer + data->curBuffer*data->bufferSize; - aluMixData(Device, buf, data->bufferSize/data->frameSize); - - result = VCALL(bq,Enqueue)(buf, data->bufferSize); - PRINTERR(result, "bq->Enqueue"); - - data->curBuffer = (data->curBuffer+1) % Device->NumUpdates; -} - - -static ALCenum opensl_open_playback(ALCdevice *Device, const ALCchar *deviceName) -{ - osl_data *data = NULL; - SLresult result; - - if(!deviceName) - deviceName = opensl_device; - else if(strcmp(deviceName, opensl_device) != 0) - return ALC_INVALID_VALUE; - - data = calloc(1, sizeof(*data)); - if(!data) - return ALC_OUT_OF_MEMORY; - - // create engine - result = slCreateEngine(&data->engineObject, 0, NULL, 0, NULL, NULL); - PRINTERR(result, "slCreateEngine"); - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->engineObject,Realize)(SL_BOOLEAN_FALSE); - PRINTERR(result, "engine->Realize"); - } - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->engineObject,GetInterface)(SL_IID_ENGINE, &data->engine); - PRINTERR(result, "engine->GetInterface"); - } - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->engine,CreateOutputMix)(&data->outputMix, 0, NULL, NULL); - PRINTERR(result, "engine->CreateOutputMix"); - } - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->outputMix,Realize)(SL_BOOLEAN_FALSE); - PRINTERR(result, "outputMix->Realize"); - } - - if(SL_RESULT_SUCCESS != result) - { - if(data->outputMix != NULL) - VCALL0(data->outputMix,Destroy)(); - data->outputMix = NULL; - - if(data->engineObject != NULL) - VCALL0(data->engineObject,Destroy)(); - data->engineObject = NULL; - data->engine = NULL; - - free(data); - return ALC_INVALID_VALUE; - } - - al_string_copy_cstr(&Device->DeviceName, deviceName); - Device->ExtraData = data; - - return ALC_NO_ERROR; -} - - -static void opensl_close_playback(ALCdevice *Device) -{ - osl_data *data = Device->ExtraData; - - if(data->bufferQueueObject != NULL) - VCALL0(data->bufferQueueObject,Destroy)(); - data->bufferQueueObject = NULL; - - VCALL0(data->outputMix,Destroy)(); - data->outputMix = NULL; - - VCALL0(data->engineObject,Destroy)(); - data->engineObject = NULL; - data->engine = NULL; - - free(data); - Device->ExtraData = NULL; -} - -static ALCboolean opensl_reset_playback(ALCdevice *Device) -{ - osl_data *data = Device->ExtraData; - SLDataLocator_AndroidSimpleBufferQueue loc_bufq; - SLDataLocator_OutputMix loc_outmix; - SLDataFormat_PCM format_pcm; - SLDataSource audioSrc; - SLDataSink audioSnk; - SLInterfaceID id; - SLboolean req; - SLresult result; - - - Device->UpdateSize = (ALuint64)Device->UpdateSize * 44100 / Device->Frequency; - Device->UpdateSize = Device->UpdateSize * Device->NumUpdates / 2; - Device->NumUpdates = 2; - - Device->Frequency = 44100; - Device->FmtChans = DevFmtStereo; - Device->FmtType = DevFmtShort; - - SetDefaultWFXChannelOrder(Device); - - - id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; - req = SL_BOOLEAN_TRUE; - - loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; - loc_bufq.numBuffers = Device->NumUpdates; - - format_pcm.formatType = SL_DATAFORMAT_PCM; - format_pcm.numChannels = ChannelsFromDevFmt(Device->FmtChans); - format_pcm.samplesPerSec = Device->Frequency * 1000; - format_pcm.bitsPerSample = BytesFromDevFmt(Device->FmtType) * 8; - format_pcm.containerSize = format_pcm.bitsPerSample; - format_pcm.channelMask = GetChannelMask(Device->FmtChans); - format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : - SL_BYTEORDER_BIGENDIAN; - - audioSrc.pLocator = &loc_bufq; - audioSrc.pFormat = &format_pcm; - - loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; - loc_outmix.outputMix = data->outputMix; - audioSnk.pLocator = &loc_outmix; - audioSnk.pFormat = NULL; - - - if(data->bufferQueueObject != NULL) - VCALL0(data->bufferQueueObject,Destroy)(); - data->bufferQueueObject = NULL; - - result = VCALL(data->engine,CreateAudioPlayer)(&data->bufferQueueObject, &audioSrc, &audioSnk, 1, &id, &req); - PRINTERR(result, "engine->CreateAudioPlayer"); - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->bufferQueueObject,Realize)(SL_BOOLEAN_FALSE); - PRINTERR(result, "bufferQueue->Realize"); - } - - if(SL_RESULT_SUCCESS != result) - { - if(data->bufferQueueObject != NULL) - VCALL0(data->bufferQueueObject,Destroy)(); - data->bufferQueueObject = NULL; - - return ALC_FALSE; - } - - return ALC_TRUE; -} - -static ALCboolean opensl_start_playback(ALCdevice *Device) -{ - osl_data *data = Device->ExtraData; - SLAndroidSimpleBufferQueueItf bufferQueue; - SLPlayItf player; - SLresult result; - ALuint i; - - result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_BUFFERQUEUE, &bufferQueue); - PRINTERR(result, "bufferQueue->GetInterface"); - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(bufferQueue,RegisterCallback)(opensl_callback, Device); - PRINTERR(result, "bufferQueue->RegisterCallback"); - } - if(SL_RESULT_SUCCESS == result) - { - data->frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); - data->bufferSize = Device->UpdateSize * data->frameSize; - data->buffer = calloc(Device->NumUpdates, data->bufferSize); - if(!data->buffer) - { - result = SL_RESULT_MEMORY_FAILURE; - PRINTERR(result, "calloc"); - } - } - /* enqueue the first buffer to kick off the callbacks */ - for(i = 0;i < Device->NumUpdates;i++) - { - if(SL_RESULT_SUCCESS == result) - { - ALvoid *buf = (ALbyte*)data->buffer + i*data->bufferSize; - result = VCALL(bufferQueue,Enqueue)(buf, data->bufferSize); - PRINTERR(result, "bufferQueue->Enqueue"); - } - } - data->curBuffer = 0; - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_PLAY, &player); - PRINTERR(result, "bufferQueue->GetInterface"); - } - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(player,SetPlayState)(SL_PLAYSTATE_PLAYING); - PRINTERR(result, "player->SetPlayState"); - } - - if(SL_RESULT_SUCCESS != result) - { - if(data->bufferQueueObject != NULL) - VCALL0(data->bufferQueueObject,Destroy)(); - data->bufferQueueObject = NULL; - - free(data->buffer); - data->buffer = NULL; - data->bufferSize = 0; - - return ALC_FALSE; - } - - return ALC_TRUE; -} - - -static void opensl_stop_playback(ALCdevice *Device) -{ - osl_data *data = Device->ExtraData; - SLPlayItf player; - SLAndroidSimpleBufferQueueItf bufferQueue; - SLresult result; - - result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_PLAY, &player); - PRINTERR(result, "bufferQueue->GetInterface"); - if(SL_RESULT_SUCCESS == result) - { - result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED); - PRINTERR(result, "player->SetPlayState"); - } - - result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_BUFFERQUEUE, &bufferQueue); - PRINTERR(result, "bufferQueue->GetInterface"); - if(SL_RESULT_SUCCESS == result) - { - result = VCALL0(bufferQueue,Clear)(); - PRINTERR(result, "bufferQueue->Clear"); - } - - free(data->buffer); - data->buffer = NULL; - data->bufferSize = 0; -} - - -static const BackendFuncs opensl_funcs = { - opensl_open_playback, - opensl_close_playback, - opensl_reset_playback, - opensl_start_playback, - opensl_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ALCdevice_GetLatencyDefault -}; - - -ALCboolean alc_opensl_init(BackendFuncs *func_list) -{ - *func_list = opensl_funcs; - return ALC_TRUE; -} - -void alc_opensl_deinit(void) -{ -} - -void alc_opensl_probe(enum DevProbe type) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - AppendAllDevicesList(opensl_device); - break; - case CAPTURE_DEVICE_PROBE: - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/portaudio.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/portaudio.c deleted file mode 100644 index 5f11526d..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/portaudio.c +++ /dev/null @@ -1,469 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include "alMain.h" -#include "alu.h" -#include "compat.h" - -#include - - -static const ALCchar pa_device[] = "PortAudio Default"; - - -#ifdef HAVE_DYNLOAD -static void *pa_handle; -#define MAKE_FUNC(x) static __typeof(x) * p##x -MAKE_FUNC(Pa_Initialize); -MAKE_FUNC(Pa_Terminate); -MAKE_FUNC(Pa_GetErrorText); -MAKE_FUNC(Pa_StartStream); -MAKE_FUNC(Pa_StopStream); -MAKE_FUNC(Pa_OpenStream); -MAKE_FUNC(Pa_CloseStream); -MAKE_FUNC(Pa_GetDefaultOutputDevice); -MAKE_FUNC(Pa_GetDefaultInputDevice); -MAKE_FUNC(Pa_GetStreamInfo); -#undef MAKE_FUNC - -#define Pa_Initialize pPa_Initialize -#define Pa_Terminate pPa_Terminate -#define Pa_GetErrorText pPa_GetErrorText -#define Pa_StartStream pPa_StartStream -#define Pa_StopStream pPa_StopStream -#define Pa_OpenStream pPa_OpenStream -#define Pa_CloseStream pPa_CloseStream -#define Pa_GetDefaultOutputDevice pPa_GetDefaultOutputDevice -#define Pa_GetDefaultInputDevice pPa_GetDefaultInputDevice -#define Pa_GetStreamInfo pPa_GetStreamInfo -#endif - -static ALCboolean pa_load(void) -{ - PaError err; - -#ifdef HAVE_DYNLOAD - if(!pa_handle) - { -#ifdef _WIN32 -# define PALIB "portaudio.dll" -#elif defined(__APPLE__) && defined(__MACH__) -# define PALIB "libportaudio.2.dylib" -#elif defined(__OpenBSD__) -# define PALIB "libportaudio.so" -#else -# define PALIB "libportaudio.so.2" -#endif - - pa_handle = LoadLib(PALIB); - if(!pa_handle) - return ALC_FALSE; - -#define LOAD_FUNC(f) do { \ - p##f = GetSymbol(pa_handle, #f); \ - if(p##f == NULL) \ - { \ - CloseLib(pa_handle); \ - pa_handle = NULL; \ - return ALC_FALSE; \ - } \ -} while(0) - LOAD_FUNC(Pa_Initialize); - LOAD_FUNC(Pa_Terminate); - LOAD_FUNC(Pa_GetErrorText); - LOAD_FUNC(Pa_StartStream); - LOAD_FUNC(Pa_StopStream); - LOAD_FUNC(Pa_OpenStream); - LOAD_FUNC(Pa_CloseStream); - LOAD_FUNC(Pa_GetDefaultOutputDevice); - LOAD_FUNC(Pa_GetDefaultInputDevice); - LOAD_FUNC(Pa_GetStreamInfo); -#undef LOAD_FUNC - - if((err=Pa_Initialize()) != paNoError) - { - ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err)); - CloseLib(pa_handle); - pa_handle = NULL; - return ALC_FALSE; - } - } -#else - if((err=Pa_Initialize()) != paNoError) - { - ERR("Pa_Initialize() returned an error: %s\n", Pa_GetErrorText(err)); - return ALC_FALSE; - } -#endif - return ALC_TRUE; -} - - -typedef struct { - PaStream *stream; - PaStreamParameters params; - ALuint update_size; - - RingBuffer *ring; -} pa_data; - - -static int pa_callback(const void *UNUSED(inputBuffer), void *outputBuffer, - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo), - const PaStreamCallbackFlags UNUSED(statusFlags), void *userData) -{ - ALCdevice *device = (ALCdevice*)userData; - - aluMixData(device, outputBuffer, framesPerBuffer); - return 0; -} - -static int pa_capture_cb(const void *inputBuffer, void *UNUSED(outputBuffer), - unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *UNUSED(timeInfo), - const PaStreamCallbackFlags UNUSED(statusFlags), void *userData) -{ - ALCdevice *device = (ALCdevice*)userData; - pa_data *data = (pa_data*)device->ExtraData; - - WriteRingBuffer(data->ring, inputBuffer, framesPerBuffer); - return 0; -} - - -static ALCenum pa_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - pa_data *data; - PaError err; - - if(!deviceName) - deviceName = pa_device; - else if(strcmp(deviceName, pa_device) != 0) - return ALC_INVALID_VALUE; - - data = (pa_data*)calloc(1, sizeof(pa_data)); - data->update_size = device->UpdateSize; - - data->params.device = -1; - if(!ConfigValueInt("port", "device", &data->params.device) || - data->params.device < 0) - data->params.device = Pa_GetDefaultOutputDevice(); - data->params.suggestedLatency = (device->UpdateSize*device->NumUpdates) / - (float)device->Frequency; - data->params.hostApiSpecificStreamInfo = NULL; - - data->params.channelCount = ((device->FmtChans == DevFmtMono) ? 1 : 2); - - switch(device->FmtType) - { - case DevFmtByte: - data->params.sampleFormat = paInt8; - break; - case DevFmtUByte: - data->params.sampleFormat = paUInt8; - break; - case DevFmtUShort: - /* fall-through */ - case DevFmtShort: - data->params.sampleFormat = paInt16; - break; - case DevFmtUInt: - /* fall-through */ - case DevFmtInt: - data->params.sampleFormat = paInt32; - break; - case DevFmtFloat: - data->params.sampleFormat = paFloat32; - break; - } - -retry_open: - err = Pa_OpenStream(&data->stream, NULL, &data->params, device->Frequency, - device->UpdateSize, paNoFlag, pa_callback, device); - if(err != paNoError) - { - if(data->params.sampleFormat == paFloat32) - { - data->params.sampleFormat = paInt16; - goto retry_open; - } - ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err)); - free(data); - return ALC_INVALID_VALUE; - } - - device->ExtraData = data; - al_string_copy_cstr(&device->DeviceName, deviceName); - - return ALC_NO_ERROR; -} - -static void pa_close_playback(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - PaError err; - - err = Pa_CloseStream(data->stream); - if(err != paNoError) - ERR("Error closing stream: %s\n", Pa_GetErrorText(err)); - - free(data); - device->ExtraData = NULL; -} - -static ALCboolean pa_reset_playback(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - const PaStreamInfo *streamInfo; - - streamInfo = Pa_GetStreamInfo(data->stream); - device->Frequency = streamInfo->sampleRate; - device->UpdateSize = data->update_size; - - if(data->params.sampleFormat == paInt8) - device->FmtType = DevFmtByte; - else if(data->params.sampleFormat == paUInt8) - device->FmtType = DevFmtUByte; - else if(data->params.sampleFormat == paInt16) - device->FmtType = DevFmtShort; - else if(data->params.sampleFormat == paInt32) - device->FmtType = DevFmtInt; - else if(data->params.sampleFormat == paFloat32) - device->FmtType = DevFmtFloat; - else - { - ERR("Unexpected sample format: 0x%lx\n", data->params.sampleFormat); - return ALC_FALSE; - } - - if(data->params.channelCount == 2) - device->FmtChans = DevFmtStereo; - else if(data->params.channelCount == 1) - device->FmtChans = DevFmtMono; - else - { - ERR("Unexpected channel count: %u\n", data->params.channelCount); - return ALC_FALSE; - } - SetDefaultChannelOrder(device); - - return ALC_TRUE; -} - -static ALCboolean pa_start_playback(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - PaError err; - - err = Pa_StartStream(data->stream); - if(err != paNoError) - { - ERR("Pa_StartStream() returned an error: %s\n", Pa_GetErrorText(err)); - return ALC_FALSE; - } - - return ALC_TRUE; -} - -static void pa_stop_playback(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - PaError err; - - err = Pa_StopStream(data->stream); - if(err != paNoError) - ERR("Error stopping stream: %s\n", Pa_GetErrorText(err)); -} - - -static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName) -{ - ALuint frame_size; - pa_data *data; - PaError err; - - if(!deviceName) - deviceName = pa_device; - else if(strcmp(deviceName, pa_device) != 0) - return ALC_INVALID_VALUE; - - data = (pa_data*)calloc(1, sizeof(pa_data)); - if(data == NULL) - return ALC_OUT_OF_MEMORY; - - frame_size = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->ring = CreateRingBuffer(frame_size, device->UpdateSize*device->NumUpdates); - if(data->ring == NULL) - goto error; - - data->params.device = -1; - if(!ConfigValueInt("port", "capture", &data->params.device) || - data->params.device < 0) - data->params.device = Pa_GetDefaultInputDevice(); - data->params.suggestedLatency = 0.0f; - data->params.hostApiSpecificStreamInfo = NULL; - - switch(device->FmtType) - { - case DevFmtByte: - data->params.sampleFormat = paInt8; - break; - case DevFmtUByte: - data->params.sampleFormat = paUInt8; - break; - case DevFmtShort: - data->params.sampleFormat = paInt16; - break; - case DevFmtInt: - data->params.sampleFormat = paInt32; - break; - case DevFmtFloat: - data->params.sampleFormat = paFloat32; - break; - case DevFmtUInt: - case DevFmtUShort: - ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType)); - goto error; - } - data->params.channelCount = ChannelsFromDevFmt(device->FmtChans); - - err = Pa_OpenStream(&data->stream, &data->params, NULL, device->Frequency, - paFramesPerBufferUnspecified, paNoFlag, pa_capture_cb, device); - if(err != paNoError) - { - ERR("Pa_OpenStream() returned an error: %s\n", Pa_GetErrorText(err)); - goto error; - } - - al_string_copy_cstr(&device->DeviceName, deviceName); - - device->ExtraData = data; - return ALC_NO_ERROR; - -error: - DestroyRingBuffer(data->ring); - free(data); - return ALC_INVALID_VALUE; -} - -static void pa_close_capture(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - PaError err; - - err = Pa_CloseStream(data->stream); - if(err != paNoError) - ERR("Error closing stream: %s\n", Pa_GetErrorText(err)); - - DestroyRingBuffer(data->ring); - data->ring = NULL; - - free(data); - device->ExtraData = NULL; -} - -static void pa_start_capture(ALCdevice *device) -{ - pa_data *data = device->ExtraData; - PaError err; - - err = Pa_StartStream(data->stream); - if(err != paNoError) - ERR("Error starting stream: %s\n", Pa_GetErrorText(err)); -} - -static void pa_stop_capture(ALCdevice *device) -{ - pa_data *data = (pa_data*)device->ExtraData; - PaError err; - - err = Pa_StopStream(data->stream); - if(err != paNoError) - ERR("Error stopping stream: %s\n", Pa_GetErrorText(err)); -} - -static ALCenum pa_capture_samples(ALCdevice *device, ALCvoid *buffer, ALCuint samples) -{ - pa_data *data = device->ExtraData; - ReadRingBuffer(data->ring, buffer, samples); - return ALC_NO_ERROR; -} - -static ALCuint pa_available_samples(ALCdevice *device) -{ - pa_data *data = device->ExtraData; - return RingBufferSize(data->ring); -} - - -static const BackendFuncs pa_funcs = { - pa_open_playback, - pa_close_playback, - pa_reset_playback, - pa_start_playback, - pa_stop_playback, - pa_open_capture, - pa_close_capture, - pa_start_capture, - pa_stop_capture, - pa_capture_samples, - pa_available_samples, - ALCdevice_GetLatencyDefault -}; - -ALCboolean alc_pa_init(BackendFuncs *func_list) -{ - if(!pa_load()) - return ALC_FALSE; - *func_list = pa_funcs; - return ALC_TRUE; -} - -void alc_pa_deinit(void) -{ -#ifdef HAVE_DYNLOAD - if(pa_handle) - { - Pa_Terminate(); - CloseLib(pa_handle); - pa_handle = NULL; - } -#else - Pa_Terminate(); -#endif -} - -void alc_pa_probe(enum DevProbe type) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - AppendAllDevicesList(pa_device); - break; - case CAPTURE_DEVICE_PROBE: - AppendCaptureDeviceList(pa_device); - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/sndio.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/sndio.c deleted file mode 100644 index 7152b2d6..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/sndio.c +++ /dev/null @@ -1,295 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include "alMain.h" -#include "alu.h" -#include "threads.h" - -#include - - -static const ALCchar sndio_device[] = "SndIO Default"; - - -static ALCboolean sndio_load(void) -{ - return ALC_TRUE; -} - - -typedef struct { - struct sio_hdl *sndHandle; - - ALvoid *mix_data; - ALsizei data_size; - - volatile int killNow; - althrd_t thread; -} sndio_data; - - -static int sndio_proc(void *ptr) -{ - ALCdevice *device = ptr; - sndio_data *data = device->ExtraData; - ALsizei frameSize; - size_t wrote; - - SetRTPriority(); - althrd_setname(althrd_current(), MIXER_THREAD_NAME); - - frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - - while(!data->killNow && device->Connected) - { - ALsizei len = data->data_size; - ALubyte *WritePtr = data->mix_data; - - aluMixData(device, WritePtr, len/frameSize); - while(len > 0 && !data->killNow) - { - wrote = sio_write(data->sndHandle, WritePtr, len); - if(wrote == 0) - { - ERR("sio_write failed\n"); - ALCdevice_Lock(device); - aluHandleDisconnect(device); - ALCdevice_Unlock(device); - break; - } - - len -= wrote; - WritePtr += wrote; - } - } - - return 0; -} - - - -static ALCenum sndio_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - sndio_data *data; - - if(!deviceName) - deviceName = sndio_device; - else if(strcmp(deviceName, sndio_device) != 0) - return ALC_INVALID_VALUE; - - data = calloc(1, sizeof(*data)); - data->killNow = 0; - - data->sndHandle = sio_open(NULL, SIO_PLAY, 0); - if(data->sndHandle == NULL) - { - free(data); - ERR("Could not open device\n"); - return ALC_INVALID_VALUE; - } - - al_string_copy_cstr(&device->DeviceName, deviceName); - device->ExtraData = data; - - return ALC_NO_ERROR; -} - -static void sndio_close_playback(ALCdevice *device) -{ - sndio_data *data = device->ExtraData; - - sio_close(data->sndHandle); - free(data); - device->ExtraData = NULL; -} - -static ALCboolean sndio_reset_playback(ALCdevice *device) -{ - sndio_data *data = device->ExtraData; - struct sio_par par; - - sio_initpar(&par); - - par.rate = device->Frequency; - par.pchan = ((device->FmtChans != DevFmtMono) ? 2 : 1); - - switch(device->FmtType) - { - case DevFmtByte: - par.bits = 8; - par.sig = 1; - break; - case DevFmtUByte: - par.bits = 8; - par.sig = 0; - break; - case DevFmtFloat: - case DevFmtShort: - par.bits = 16; - par.sig = 1; - break; - case DevFmtUShort: - par.bits = 16; - par.sig = 0; - break; - case DevFmtInt: - par.bits = 32; - par.sig = 1; - break; - case DevFmtUInt: - par.bits = 32; - par.sig = 0; - break; - } - par.le = SIO_LE_NATIVE; - - par.round = device->UpdateSize; - par.appbufsz = device->UpdateSize * (device->NumUpdates-1); - if(!par.appbufsz) par.appbufsz = device->UpdateSize; - - if(!sio_setpar(data->sndHandle, &par) || !sio_getpar(data->sndHandle, &par)) - { - ERR("Failed to set device parameters\n"); - return ALC_FALSE; - } - - if(par.bits != par.bps*8) - { - ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8); - return ALC_FALSE; - } - - device->Frequency = par.rate; - device->FmtChans = ((par.pchan==1) ? DevFmtMono : DevFmtStereo); - - if(par.bits == 8 && par.sig == 1) - device->FmtType = DevFmtByte; - else if(par.bits == 8 && par.sig == 0) - device->FmtType = DevFmtUByte; - else if(par.bits == 16 && par.sig == 1) - device->FmtType = DevFmtShort; - else if(par.bits == 16 && par.sig == 0) - device->FmtType = DevFmtUShort; - else if(par.bits == 32 && par.sig == 1) - device->FmtType = DevFmtInt; - else if(par.bits == 32 && par.sig == 0) - device->FmtType = DevFmtUInt; - else - { - ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits); - return ALC_FALSE; - } - - device->UpdateSize = par.round; - device->NumUpdates = (par.bufsz/par.round) + 1; - - SetDefaultChannelOrder(device); - - return ALC_TRUE; -} - -static ALCboolean sndio_start_playback(ALCdevice *device) -{ - sndio_data *data = device->ExtraData; - - if(!sio_start(data->sndHandle)) - { - ERR("Error starting playback\n"); - return ALC_FALSE; - } - - data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->mix_data = calloc(1, data->data_size); - - data->killNow = 0; - if(althrd_create(&data->thread, sndio_proc, device) != althrd_success) - { - sio_stop(data->sndHandle); - free(data->mix_data); - data->mix_data = NULL; - return ALC_FALSE; - } - - return ALC_TRUE; -} - -static void sndio_stop_playback(ALCdevice *device) -{ - sndio_data *data = device->ExtraData; - int res; - - if(data->killNow) - return; - - data->killNow = 1; - althrd_join(data->thread, &res); - - if(!sio_stop(data->sndHandle)) - ERR("Error stopping device\n"); - - free(data->mix_data); - data->mix_data = NULL; -} - - -static const BackendFuncs sndio_funcs = { - sndio_open_playback, - sndio_close_playback, - sndio_reset_playback, - sndio_start_playback, - sndio_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ALCdevice_GetLatencyDefault -}; - -ALCboolean alc_sndio_init(BackendFuncs *func_list) -{ - if(!sndio_load()) - return ALC_FALSE; - *func_list = sndio_funcs; - return ALC_TRUE; -} - -void alc_sndio_deinit(void) -{ -} - -void alc_sndio_probe(enum DevProbe type) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - AppendAllDevicesList(sndio_device); - break; - case CAPTURE_DEVICE_PROBE: - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/solaris.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/solaris.c deleted file mode 100644 index 20d861d2..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/solaris.c +++ /dev/null @@ -1,288 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alMain.h" -#include "alu.h" -#include "threads.h" -#include "compat.h" - -#include - - -static const ALCchar solaris_device[] = "Solaris Default"; - -static const char *solaris_driver = "/dev/audio"; - -typedef struct { - int fd; - - ALubyte *mix_data; - int data_size; - - volatile int killNow; - althrd_t thread; -} solaris_data; - - -static int SolarisProc(void *ptr) -{ - ALCdevice *Device = (ALCdevice*)ptr; - solaris_data *data = (solaris_data*)Device->ExtraData; - ALint frameSize; - int wrote; - - SetRTPriority(); - althrd_setname(althrd_current(), MIXER_THREAD_NAME); - - frameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); - - while(!data->killNow && Device->Connected) - { - ALint len = data->data_size; - ALubyte *WritePtr = data->mix_data; - - aluMixData(Device, WritePtr, len/frameSize); - while(len > 0 && !data->killNow) - { - wrote = write(data->fd, WritePtr, len); - if(wrote < 0) - { - if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) - { - ERR("write failed: %s\n", strerror(errno)); - ALCdevice_Lock(Device); - aluHandleDisconnect(Device); - ALCdevice_Unlock(Device); - break; - } - - al_nssleep(0, 1000000); - continue; - } - - len -= wrote; - WritePtr += wrote; - } - } - - return 0; -} - - -static ALCenum solaris_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - solaris_data *data; - - if(!deviceName) - deviceName = solaris_device; - else if(strcmp(deviceName, solaris_device) != 0) - return ALC_INVALID_VALUE; - - data = (solaris_data*)calloc(1, sizeof(solaris_data)); - data->killNow = 0; - - data->fd = open(solaris_driver, O_WRONLY); - if(data->fd == -1) - { - free(data); - ERR("Could not open %s: %s\n", solaris_driver, strerror(errno)); - return ALC_INVALID_VALUE; - } - - al_string_copy_cstr(&device->DeviceName, deviceName); - device->ExtraData = data; - return ALC_NO_ERROR; -} - -static void solaris_close_playback(ALCdevice *device) -{ - solaris_data *data = (solaris_data*)device->ExtraData; - - close(data->fd); - free(data); - device->ExtraData = NULL; -} - -static ALCboolean solaris_reset_playback(ALCdevice *device) -{ - solaris_data *data = (solaris_data*)device->ExtraData; - audio_info_t info; - ALuint frameSize; - int numChannels; - - AUDIO_INITINFO(&info); - - info.play.sample_rate = device->Frequency; - - if(device->FmtChans != DevFmtMono) - device->FmtChans = DevFmtStereo; - numChannels = ChannelsFromDevFmt(device->FmtChans); - info.play.channels = numChannels; - - switch(device->FmtType) - { - case DevFmtByte: - info.play.precision = 8; - info.play.encoding = AUDIO_ENCODING_LINEAR; - break; - case DevFmtUByte: - info.play.precision = 8; - info.play.encoding = AUDIO_ENCODING_LINEAR8; - break; - case DevFmtUShort: - case DevFmtInt: - case DevFmtUInt: - case DevFmtFloat: - device->FmtType = DevFmtShort; - /* fall-through */ - case DevFmtShort: - info.play.precision = 16; - info.play.encoding = AUDIO_ENCODING_LINEAR; - break; - } - - frameSize = numChannels * BytesFromDevFmt(device->FmtType); - info.play.buffer_size = device->UpdateSize*device->NumUpdates * frameSize; - - if(ioctl(data->fd, AUDIO_SETINFO, &info) < 0) - { - ERR("ioctl failed: %s\n", strerror(errno)); - return ALC_FALSE; - } - - if(ChannelsFromDevFmt(device->FmtChans) != info.play.channels) - { - ERR("Could not set %d channels, got %d instead\n", ChannelsFromDevFmt(device->FmtChans), info.play.channels); - return ALC_FALSE; - } - - if(!((info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 && device->FmtType == DevFmtUByte) || - (info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtByte) || - (info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtShort) || - (info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR && device->FmtType == DevFmtInt))) - { - ERR("Could not set %s samples, got %d (0x%x)\n", DevFmtTypeString(device->FmtType), - info.play.precision, info.play.encoding); - return ALC_FALSE; - } - - device->Frequency = info.play.sample_rate; - device->UpdateSize = (info.play.buffer_size/device->NumUpdates) + 1; - - SetDefaultChannelOrder(device); - - return ALC_TRUE; -} - -static ALCboolean solaris_start_playback(ALCdevice *device) -{ - solaris_data *data = (solaris_data*)device->ExtraData; - - data->data_size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->mix_data = calloc(1, data->data_size); - - data->killNow = 0; - if(althrd_create(&data->thread, SolarisProc, device) != althrd_success) - { - free(data->mix_data); - data->mix_data = NULL; - return ALC_FALSE; - } - - return ALC_TRUE; -} - -static void solaris_stop_playback(ALCdevice *device) -{ - solaris_data *data = (solaris_data*)device->ExtraData; - int res; - - if(data->killNow) - return; - - data->killNow = 1; - althrd_join(data->thread, &res); - - if(ioctl(data->fd, AUDIO_DRAIN) < 0) - ERR("Error draining device: %s\n", strerror(errno)); - - free(data->mix_data); - data->mix_data = NULL; -} - - -static const BackendFuncs solaris_funcs = { - solaris_open_playback, - solaris_close_playback, - solaris_reset_playback, - solaris_start_playback, - solaris_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ALCdevice_GetLatencyDefault -}; - -ALCboolean alc_solaris_init(BackendFuncs *func_list) -{ - ConfigValueStr("solaris", "device", &solaris_driver); - - *func_list = solaris_funcs; - return ALC_TRUE; -} - -void alc_solaris_deinit(void) -{ -} - -void alc_solaris_probe(enum DevProbe type) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - { -#ifdef HAVE_STAT - struct stat buf; - if(stat(solaris_driver, &buf) == 0) -#endif - AppendAllDevicesList(solaris_device); - } - break; - - case CAPTURE_DEVICE_PROBE: - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/wave.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/wave.c deleted file mode 100644 index 421ca5d7..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/wave.c +++ /dev/null @@ -1,377 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include -#ifdef HAVE_WINDOWS_H -#include -#endif - -#include "alMain.h" -#include "alu.h" -#include "threads.h" -#include "compat.h" - - -typedef struct { - FILE *f; - long DataStart; - - ALvoid *buffer; - ALuint size; - - volatile int killNow; - althrd_t thread; -} wave_data; - - -static const ALCchar waveDevice[] = "Wave File Writer"; - -static const ALubyte SUBTYPE_PCM[] = { - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, - 0x00, 0x38, 0x9b, 0x71 -}; -static const ALubyte SUBTYPE_FLOAT[] = { - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0xaa, - 0x00, 0x38, 0x9b, 0x71 -}; - -static const ALuint channel_masks[] = { - 0, /* invalid */ - 0x4, /* Mono */ - 0x1 | 0x2, /* Stereo */ - 0, /* 3 channel */ - 0x1 | 0x2 | 0x10 | 0x20, /* Quad */ - 0, /* 5 channel */ - 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20, /* 5.1 */ - 0x1 | 0x2 | 0x4 | 0x8 | 0x100 | 0x200 | 0x400, /* 6.1 */ - 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x200 | 0x400, /* 7.1 */ -}; - - -static void fwrite16le(ALushort val, FILE *f) -{ - fputc(val&0xff, f); - fputc((val>>8)&0xff, f); -} - -static void fwrite32le(ALuint val, FILE *f) -{ - fputc(val&0xff, f); - fputc((val>>8)&0xff, f); - fputc((val>>16)&0xff, f); - fputc((val>>24)&0xff, f); -} - - -static int WaveProc(void *ptr) -{ - ALCdevice *device = (ALCdevice*)ptr; - wave_data *data = (wave_data*)device->ExtraData; - struct timespec now, start; - ALint64 avail, done; - ALuint frameSize; - size_t fs; - const long restTime = (long)((ALuint64)device->UpdateSize * 1000000000 / - device->Frequency / 2); - - althrd_setname(althrd_current(), MIXER_THREAD_NAME); - - frameSize = FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - - done = 0; - if(altimespec_get(&start, AL_TIME_UTC) != AL_TIME_UTC) - { - ERR("Failed to get starting time\n"); - return 1; - } - while(!data->killNow && device->Connected) - { - if(altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC) - { - ERR("Failed to get current time\n"); - return 1; - } - - avail = (now.tv_sec - start.tv_sec) * device->Frequency; - avail += (ALint64)(now.tv_nsec - start.tv_nsec) * device->Frequency / 1000000000; - if(avail < done) - { - /* Oops, time skipped backwards. Reset the number of samples done - * with one update available since we (likely) just came back from - * sleeping. */ - done = avail - device->UpdateSize; - } - - if(avail-done < device->UpdateSize) - al_nssleep(0, restTime); - else while(avail-done >= device->UpdateSize) - { - aluMixData(device, data->buffer, device->UpdateSize); - done += device->UpdateSize; - - if(!IS_LITTLE_ENDIAN) - { - ALuint bytesize = BytesFromDevFmt(device->FmtType); - ALubyte *bytes = data->buffer; - ALuint i; - - if(bytesize == 1) - { - for(i = 0;i < data->size;i++) - fputc(bytes[i], data->f); - } - else if(bytesize == 2) - { - for(i = 0;i < data->size;i++) - fputc(bytes[i^1], data->f); - } - else if(bytesize == 4) - { - for(i = 0;i < data->size;i++) - fputc(bytes[i^3], data->f); - } - } - else - { - fs = fwrite(data->buffer, frameSize, device->UpdateSize, - data->f); - (void)fs; - } - if(ferror(data->f)) - { - ERR("Error writing to file\n"); - ALCdevice_Lock(device); - aluHandleDisconnect(device); - ALCdevice_Unlock(device); - break; - } - } - } - - return 0; -} - -static ALCenum wave_open_playback(ALCdevice *device, const ALCchar *deviceName) -{ - wave_data *data; - const char *fname; - - fname = GetConfigValue("wave", "file", ""); - if(!fname[0]) - return ALC_INVALID_VALUE; - - if(!deviceName) - deviceName = waveDevice; - else if(strcmp(deviceName, waveDevice) != 0) - return ALC_INVALID_VALUE; - - data = (wave_data*)calloc(1, sizeof(wave_data)); - - data->f = al_fopen(fname, "wb"); - if(!data->f) - { - free(data); - ERR("Could not open file '%s': %s\n", fname, strerror(errno)); - return ALC_INVALID_VALUE; - } - - al_string_copy_cstr(&device->DeviceName, deviceName); - device->ExtraData = data; - return ALC_NO_ERROR; -} - -static void wave_close_playback(ALCdevice *device) -{ - wave_data *data = (wave_data*)device->ExtraData; - - fclose(data->f); - free(data); - device->ExtraData = NULL; -} - -static ALCboolean wave_reset_playback(ALCdevice *device) -{ - wave_data *data = (wave_data*)device->ExtraData; - ALuint channels=0, bits=0; - size_t val; - - fseek(data->f, 0, SEEK_SET); - clearerr(data->f); - - switch(device->FmtType) - { - case DevFmtByte: - device->FmtType = DevFmtUByte; - break; - case DevFmtUShort: - device->FmtType = DevFmtShort; - break; - case DevFmtUInt: - device->FmtType = DevFmtInt; - break; - case DevFmtUByte: - case DevFmtShort: - case DevFmtInt: - case DevFmtFloat: - break; - } - bits = BytesFromDevFmt(device->FmtType) * 8; - channels = ChannelsFromDevFmt(device->FmtChans); - - fprintf(data->f, "RIFF"); - fwrite32le(0xFFFFFFFF, data->f); // 'RIFF' header len; filled in at close - - fprintf(data->f, "WAVE"); - - fprintf(data->f, "fmt "); - fwrite32le(40, data->f); // 'fmt ' header len; 40 bytes for EXTENSIBLE - - // 16-bit val, format type id (extensible: 0xFFFE) - fwrite16le(0xFFFE, data->f); - // 16-bit val, channel count - fwrite16le(channels, data->f); - // 32-bit val, frequency - fwrite32le(device->Frequency, data->f); - // 32-bit val, bytes per second - fwrite32le(device->Frequency * channels * bits / 8, data->f); - // 16-bit val, frame size - fwrite16le(channels * bits / 8, data->f); - // 16-bit val, bits per sample - fwrite16le(bits, data->f); - // 16-bit val, extra byte count - fwrite16le(22, data->f); - // 16-bit val, valid bits per sample - fwrite16le(bits, data->f); - // 32-bit val, channel mask - fwrite32le(channel_masks[channels], data->f); - // 16 byte GUID, sub-type format - val = fwrite(((bits==32) ? SUBTYPE_FLOAT : SUBTYPE_PCM), 1, 16, data->f); - (void)val; - - fprintf(data->f, "data"); - fwrite32le(0xFFFFFFFF, data->f); // 'data' header len; filled in at close - - if(ferror(data->f)) - { - ERR("Error writing header: %s\n", strerror(errno)); - return ALC_FALSE; - } - data->DataStart = ftell(data->f); - - SetDefaultWFXChannelOrder(device); - - return ALC_TRUE; -} - -static ALCboolean wave_start_playback(ALCdevice *device) -{ - wave_data *data = (wave_data*)device->ExtraData; - - data->size = device->UpdateSize * FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - data->buffer = malloc(data->size); - if(!data->buffer) - { - ERR("Buffer malloc failed\n"); - return ALC_FALSE; - } - - data->killNow = 0; - if(althrd_create(&data->thread, WaveProc, device) != althrd_success) - { - free(data->buffer); - data->buffer = NULL; - return ALC_FALSE; - } - - return ALC_TRUE; -} - -static void wave_stop_playback(ALCdevice *device) -{ - wave_data *data = (wave_data*)device->ExtraData; - ALuint dataLen; - long size; - int res; - - if(data->killNow) - return; - - data->killNow = 1; - althrd_join(data->thread, &res); - - free(data->buffer); - data->buffer = NULL; - - size = ftell(data->f); - if(size > 0) - { - dataLen = size - data->DataStart; - if(fseek(data->f, data->DataStart-4, SEEK_SET) == 0) - fwrite32le(dataLen, data->f); // 'data' header len - if(fseek(data->f, 4, SEEK_SET) == 0) - fwrite32le(size-8, data->f); // 'WAVE' header len - } -} - - -static const BackendFuncs wave_funcs = { - wave_open_playback, - wave_close_playback, - wave_reset_playback, - wave_start_playback, - wave_stop_playback, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ALCdevice_GetLatencyDefault -}; - -ALCboolean alc_wave_init(BackendFuncs *func_list) -{ - *func_list = wave_funcs; - return ALC_TRUE; -} - -void alc_wave_deinit(void) -{ -} - -void alc_wave_probe(enum DevProbe type) -{ - if(!ConfigValueExists("wave", "file")) - return; - - switch(type) - { - case ALL_DEVICE_PROBE: - AppendAllDevicesList(waveDevice); - break; - case CAPTURE_DEVICE_PROBE: - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/backends/winmm.c b/love/src/jni/openal-soft-1.17.0/Alc/backends/winmm.c deleted file mode 100644 index cad66470..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/backends/winmm.c +++ /dev/null @@ -1,716 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include -#include - -#include "alMain.h" -#include "alu.h" -#include "threads.h" - -#ifndef WAVE_FORMAT_IEEE_FLOAT -#define WAVE_FORMAT_IEEE_FLOAT 0x0003 -#endif - - -typedef struct { - // MMSYSTEM Device - volatile ALboolean killNow; - althrd_t thread; - - RefCount WaveBuffersCommitted; - WAVEHDR WaveBuffer[4]; - - union { - HWAVEIN In; - HWAVEOUT Out; - } WaveHandle; - - WAVEFORMATEX Format; - - RingBuffer *Ring; -} WinMMData; - - -TYPEDEF_VECTOR(al_string, vector_al_string) -static vector_al_string PlaybackDevices; -static vector_al_string CaptureDevices; - -static void clear_devlist(vector_al_string *list) -{ - VECTOR_FOR_EACH(al_string, *list, al_string_deinit); - VECTOR_RESIZE(*list, 0); -} - - -static void ProbePlaybackDevices(void) -{ - al_string *iter, *end; - ALuint numdevs; - ALuint i; - - clear_devlist(&PlaybackDevices); - - numdevs = waveOutGetNumDevs(); - VECTOR_RESERVE(PlaybackDevices, numdevs); - for(i = 0;i < numdevs;i++) - { - WAVEOUTCAPSW WaveCaps; - al_string dname; - - AL_STRING_INIT(dname); - if(waveOutGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) - { - ALuint count = 0; - do { - al_string_copy_wcstr(&dname, WaveCaps.szPname); - if(count != 0) - { - char str[64]; - snprintf(str, sizeof(str), " #%d", count+1); - al_string_append_cstr(&dname, str); - } - count++; - - iter = VECTOR_ITER_BEGIN(PlaybackDevices); - end = VECTOR_ITER_END(PlaybackDevices); - for(;iter != end;iter++) - { - if(al_string_cmp(*iter, dname) == 0) - break; - } - } while(iter != end); - - TRACE("Got device \"%s\", ID %u\n", al_string_get_cstr(dname), i); - } - VECTOR_PUSH_BACK(PlaybackDevices, dname); - } -} - -static void ProbeCaptureDevices(void) -{ - al_string *iter, *end; - ALuint numdevs; - ALuint i; - - clear_devlist(&CaptureDevices); - - numdevs = waveInGetNumDevs(); - VECTOR_RESERVE(CaptureDevices, numdevs); - for(i = 0;i < numdevs;i++) - { - WAVEINCAPSW WaveCaps; - al_string dname; - - AL_STRING_INIT(dname); - if(waveInGetDevCapsW(i, &WaveCaps, sizeof(WaveCaps)) == MMSYSERR_NOERROR) - { - ALuint count = 0; - do { - al_string_copy_wcstr(&dname, WaveCaps.szPname); - if(count != 0) - { - char str[64]; - snprintf(str, sizeof(str), " #%d", count+1); - al_string_append_cstr(&dname, str); - } - count++; - - iter = VECTOR_ITER_BEGIN(CaptureDevices); - end = VECTOR_ITER_END(CaptureDevices); - for(;iter != end;iter++) - { - if(al_string_cmp(*iter, dname) == 0) - break; - } - } while(iter != end); - - TRACE("Got device \"%s\", ID %u\n", al_string_get_cstr(dname), i); - } - VECTOR_PUSH_BACK(CaptureDevices, dname); - } -} - - -/* - WaveOutProc - - Posts a message to 'PlaybackThreadProc' everytime a WaveOut Buffer is completed and - returns to the application (for more data) -*/ -static void CALLBACK WaveOutProc(HWAVEOUT UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) -{ - ALCdevice *Device = (ALCdevice*)instance; - WinMMData *data = Device->ExtraData; - - if(msg != WOM_DONE) - return; - - DecrementRef(&data->WaveBuffersCommitted); - PostThreadMessage(data->thread, msg, 0, param1); -} - -FORCE_ALIGN static int PlaybackThreadProc(void *arg) -{ - ALCdevice *Device = (ALCdevice*)arg; - WinMMData *data = Device->ExtraData; - WAVEHDR *WaveHdr; - MSG msg; - - SetRTPriority(); - althrd_setname(althrd_current(), MIXER_THREAD_NAME); - - while(GetMessage(&msg, NULL, 0, 0)) - { - if(msg.message != WOM_DONE) - continue; - - if(data->killNow) - { - if(ReadRef(&data->WaveBuffersCommitted) == 0) - break; - continue; - } - - WaveHdr = ((WAVEHDR*)msg.lParam); - aluMixData(Device, WaveHdr->lpData, WaveHdr->dwBufferLength / - data->Format.nBlockAlign); - - // Send buffer back to play more data - waveOutWrite(data->WaveHandle.Out, WaveHdr, sizeof(WAVEHDR)); - IncrementRef(&data->WaveBuffersCommitted); - } - - return 0; -} - -/* - WaveInProc - - Posts a message to 'CaptureThreadProc' everytime a WaveIn Buffer is completed and - returns to the application (with more data) -*/ -static void CALLBACK WaveInProc(HWAVEIN UNUSED(device), UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR UNUSED(param2)) -{ - ALCdevice *Device = (ALCdevice*)instance; - WinMMData *data = Device->ExtraData; - - if(msg != WIM_DATA) - return; - - DecrementRef(&data->WaveBuffersCommitted); - PostThreadMessage(data->thread, msg, 0, param1); -} - -static int CaptureThreadProc(void *arg) -{ - ALCdevice *Device = (ALCdevice*)arg; - WinMMData *data = Device->ExtraData; - WAVEHDR *WaveHdr; - MSG msg; - - althrd_setname(althrd_current(), "alsoft-record"); - - while(GetMessage(&msg, NULL, 0, 0)) - { - if(msg.message != WIM_DATA) - continue; - /* Don't wait for other buffers to finish before quitting. We're - * closing so we don't need them. */ - if(data->killNow) - break; - - WaveHdr = ((WAVEHDR*)msg.lParam); - WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, - WaveHdr->dwBytesRecorded/data->Format.nBlockAlign); - - // Send buffer back to capture more data - waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR)); - IncrementRef(&data->WaveBuffersCommitted); - } - - return 0; -} - - -static ALCenum WinMMOpenPlayback(ALCdevice *Device, const ALCchar *deviceName) -{ - WinMMData *data = NULL; - const al_string *iter, *end; - UINT DeviceID; - MMRESULT res; - - if(VECTOR_SIZE(PlaybackDevices) == 0) - ProbePlaybackDevices(); - - // Find the Device ID matching the deviceName if valid - iter = VECTOR_ITER_BEGIN(PlaybackDevices); - end = VECTOR_ITER_END(PlaybackDevices); - for(;iter != end;iter++) - { - if(!al_string_empty(*iter) && - (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0)) - { - DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(PlaybackDevices)); - break; - } - } - if(iter == end) - return ALC_INVALID_VALUE; - - data = calloc(1, sizeof(*data)); - if(!data) - return ALC_OUT_OF_MEMORY; - Device->ExtraData = data; - -retry_open: - memset(&data->Format, 0, sizeof(WAVEFORMATEX)); - if(Device->FmtType == DevFmtFloat) - { - data->Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - data->Format.wBitsPerSample = 32; - } - else - { - data->Format.wFormatTag = WAVE_FORMAT_PCM; - if(Device->FmtType == DevFmtUByte || Device->FmtType == DevFmtByte) - data->Format.wBitsPerSample = 8; - else - data->Format.wBitsPerSample = 16; - } - 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(&data->WaveHandle.Out, DeviceID, &data->Format, (DWORD_PTR)&WaveOutProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) - { - if(Device->FmtType == DevFmtFloat) - { - Device->FmtType = DevFmtShort; - goto retry_open; - } - ERR("waveOutOpen failed: %u\n", res); - goto failure; - } - - al_string_copy(&Device->DeviceName, VECTOR_ELEM(PlaybackDevices, DeviceID)); - return ALC_NO_ERROR; - -failure: - if(data->WaveHandle.Out) - waveOutClose(data->WaveHandle.Out); - - free(data); - Device->ExtraData = NULL; - return ALC_INVALID_VALUE; -} - -static void WinMMClosePlayback(ALCdevice *device) -{ - WinMMData *data = (WinMMData*)device->ExtraData; - - // Close the Wave device - waveOutClose(data->WaveHandle.Out); - data->WaveHandle.Out = 0; - - free(data); - device->ExtraData = NULL; -} - -static ALCboolean WinMMResetPlayback(ALCdevice *device) -{ - WinMMData *data = (WinMMData*)device->ExtraData; - - device->UpdateSize = (ALuint)((ALuint64)device->UpdateSize * - data->Format.nSamplesPerSec / - device->Frequency); - device->UpdateSize = (device->UpdateSize*device->NumUpdates + 3) / 4; - device->NumUpdates = 4; - device->Frequency = data->Format.nSamplesPerSec; - - if(data->Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) - { - if(data->Format.wBitsPerSample == 32) - device->FmtType = DevFmtFloat; - else - { - ERR("Unhandled IEEE float sample depth: %d\n", data->Format.wBitsPerSample); - return ALC_FALSE; - } - } - else if(data->Format.wFormatTag == WAVE_FORMAT_PCM) - { - if(data->Format.wBitsPerSample == 16) - device->FmtType = DevFmtShort; - else if(data->Format.wBitsPerSample == 8) - device->FmtType = DevFmtUByte; - else - { - ERR("Unhandled PCM sample depth: %d\n", data->Format.wBitsPerSample); - return ALC_FALSE; - } - } - else - { - ERR("Unhandled format tag: 0x%04x\n", data->Format.wFormatTag); - return ALC_FALSE; - } - - if(data->Format.nChannels == 2) - device->FmtChans = DevFmtStereo; - else if(data->Format.nChannels == 1) - device->FmtChans = DevFmtMono; - else - { - ERR("Unhandled channel count: %d\n", data->Format.nChannels); - return ALC_FALSE; - } - SetDefaultWFXChannelOrder(device); - - return ALC_TRUE; -} - -static ALCboolean WinMMStartPlayback(ALCdevice *device) -{ - WinMMData *data = (WinMMData*)device->ExtraData; - ALbyte *BufferData; - ALint BufferSize; - ALuint i; - - data->killNow = AL_FALSE; - if(althrd_create(&data->thread, PlaybackThreadProc, device) != althrd_success) - return ALC_FALSE; - - InitRef(&data->WaveBuffersCommitted, 0); - - // Create 4 Buffers - BufferSize = device->UpdateSize*device->NumUpdates / 4; - BufferSize *= FrameSizeFromDevFmt(device->FmtChans, device->FmtType); - - BufferData = calloc(4, BufferSize); - for(i = 0;i < 4;i++) - { - memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR)); - data->WaveBuffer[i].dwBufferLength = BufferSize; - data->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)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)); - IncrementRef(&data->WaveBuffersCommitted); - } - - return ALC_TRUE; -} - -static void WinMMStopPlayback(ALCdevice *device) -{ - WinMMData *data = (WinMMData*)device->ExtraData; - void *buffer = NULL; - int i; - - if(data->killNow) - return; - - // Set flag to stop processing headers - data->killNow = AL_TRUE; - althrd_join(data->thread, &i); - - // Release the wave buffers - for(i = 0;i < 4;i++) - { - 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 *Device, const ALCchar *deviceName) -{ - const al_string *iter, *end; - ALbyte *BufferData = NULL; - DWORD CapturedDataSize; - WinMMData *data = NULL; - ALint BufferSize; - UINT DeviceID; - MMRESULT res; - ALuint i; - - if(VECTOR_SIZE(CaptureDevices) == 0) - ProbeCaptureDevices(); - - // Find the Device ID matching the deviceName if valid - iter = VECTOR_ITER_BEGIN(CaptureDevices); - end = VECTOR_ITER_END(CaptureDevices); - for(;iter != end;iter++) - { - if(!al_string_empty(*iter) && - (!deviceName || al_string_cmp_cstr(*iter, deviceName) == 0)) - { - DeviceID = (UINT)(iter - VECTOR_ITER_BEGIN(CaptureDevices)); - break; - } - } - if(iter == end) - return ALC_INVALID_VALUE; - - switch(Device->FmtChans) - { - case DevFmtMono: - case DevFmtStereo: - break; - - case DevFmtQuad: - case DevFmtX51: - case DevFmtX51Side: - case DevFmtX61: - case DevFmtX71: - return ALC_INVALID_ENUM; - } - - switch(Device->FmtType) - { - case DevFmtUByte: - case DevFmtShort: - case DevFmtInt: - case DevFmtFloat: - break; - - case DevFmtByte: - case DevFmtUShort: - case DevFmtUInt: - return ALC_INVALID_ENUM; - } - - data = calloc(1, sizeof(*data)); - if(!data) - return ALC_OUT_OF_MEMORY; - Device->ExtraData = data; - - 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(&data->WaveHandle.In, DeviceID, &data->Format, (DWORD_PTR)&WaveInProc, (DWORD_PTR)Device, CALLBACK_FUNCTION)) != MMSYSERR_NOERROR) - { - ERR("waveInOpen failed: %u\n", res); - goto failure; - } - - // Allocate circular memory buffer for the captured audio - CapturedDataSize = Device->UpdateSize*Device->NumUpdates; - - // Make sure circular buffer is at least 100ms in size - if(CapturedDataSize < (data->Format.nSamplesPerSec / 10)) - CapturedDataSize = data->Format.nSamplesPerSec / 10; - - data->Ring = CreateRingBuffer(data->Format.nBlockAlign, CapturedDataSize); - if(!data->Ring) - goto failure; - - InitRef(&data->WaveBuffersCommitted, 0); - - // Create 4 Buffers of 50ms each - BufferSize = data->Format.nAvgBytesPerSec / 20; - BufferSize -= (BufferSize % data->Format.nBlockAlign); - - BufferData = calloc(4, BufferSize); - if(!BufferData) - goto failure; - - for(i = 0;i < 4;i++) - { - memset(&data->WaveBuffer[i], 0, sizeof(WAVEHDR)); - data->WaveBuffer[i].dwBufferLength = BufferSize; - data->WaveBuffer[i].lpData = ((i==0) ? (CHAR*)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)); - IncrementRef(&data->WaveBuffersCommitted); - } - - if(althrd_create(&data->thread, CaptureThreadProc, Device) != althrd_success) - goto failure; - - al_string_copy(&Device->DeviceName, VECTOR_ELEM(CaptureDevices, DeviceID)); - return ALC_NO_ERROR; - -failure: - if(BufferData) - { - for(i = 0;i < 4;i++) - waveInUnprepareHeader(data->WaveHandle.In, &data->WaveBuffer[i], sizeof(WAVEHDR)); - free(BufferData); - } - - if(data->Ring) - DestroyRingBuffer(data->Ring); - - if(data->WaveHandle.In) - waveInClose(data->WaveHandle.In); - - free(data); - Device->ExtraData = NULL; - return ALC_INVALID_VALUE; -} - -static void WinMMCloseCapture(ALCdevice *Device) -{ - WinMMData *data = (WinMMData*)Device->ExtraData; - void *buffer = NULL; - int i; - - /* Tell the processing thread to quit and wait for it to do so. */ - data->killNow = AL_TRUE; - PostThreadMessage(data->thread, WM_QUIT, 0, 0); - - althrd_join(data->thread, &i); - - /* Make sure capture is stopped and all pending buffers are flushed. */ - waveInReset(data->WaveHandle.In); - - // Release the wave buffers - for(i = 0;i < 4;i++) - { - 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(data->Ring); - data->Ring = NULL; - - // Close the Wave device - waveInClose(data->WaveHandle.In); - data->WaveHandle.In = 0; - - free(data); - Device->ExtraData = NULL; -} - -static void WinMMStartCapture(ALCdevice *Device) -{ - WinMMData *data = (WinMMData*)Device->ExtraData; - waveInStart(data->WaveHandle.In); -} - -static void WinMMStopCapture(ALCdevice *Device) -{ - WinMMData *data = (WinMMData*)Device->ExtraData; - waveInStop(data->WaveHandle.In); -} - -static ALCenum WinMMCaptureSamples(ALCdevice *Device, ALCvoid *Buffer, ALCuint Samples) -{ - WinMMData *data = (WinMMData*)Device->ExtraData; - ReadRingBuffer(data->Ring, Buffer, Samples); - return ALC_NO_ERROR; -} - -static ALCuint WinMMAvailableSamples(ALCdevice *Device) -{ - WinMMData *data = (WinMMData*)Device->ExtraData; - return RingBufferSize(data->Ring); -} - - -static inline void AppendAllDevicesList2(const al_string *name) -{ - if(!al_string_empty(*name)) - AppendAllDevicesList(al_string_get_cstr(*name)); -} -static inline void AppendCaptureDeviceList2(const al_string *name) -{ - if(!al_string_empty(*name)) - AppendCaptureDeviceList(al_string_get_cstr(*name)); -} - -static const BackendFuncs WinMMFuncs = { - WinMMOpenPlayback, - WinMMClosePlayback, - WinMMResetPlayback, - WinMMStartPlayback, - WinMMStopPlayback, - WinMMOpenCapture, - WinMMCloseCapture, - WinMMStartCapture, - WinMMStopCapture, - WinMMCaptureSamples, - WinMMAvailableSamples, - ALCdevice_GetLatencyDefault -}; - -ALCboolean alcWinMMInit(BackendFuncs *FuncList) -{ - VECTOR_INIT(PlaybackDevices); - VECTOR_INIT(CaptureDevices); - - *FuncList = WinMMFuncs; - return ALC_TRUE; -} - -void alcWinMMDeinit() -{ - clear_devlist(&PlaybackDevices); - VECTOR_DEINIT(PlaybackDevices); - - clear_devlist(&CaptureDevices); - VECTOR_DEINIT(CaptureDevices); -} - -void alcWinMMProbe(enum DevProbe type) -{ - switch(type) - { - case ALL_DEVICE_PROBE: - ProbePlaybackDevices(); - VECTOR_FOR_EACH(const al_string, PlaybackDevices, AppendAllDevicesList2); - break; - - case CAPTURE_DEVICE_PROBE: - ProbeCaptureDevices(); - VECTOR_FOR_EACH(const al_string, CaptureDevices, AppendCaptureDeviceList2); - break; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/effects/autowah.c b/love/src/jni/openal-soft-1.17.0/Alc/effects/autowah.c deleted file mode 100644 index c8317c8b..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/effects/autowah.c +++ /dev/null @@ -1,272 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2013 by Anis A. Hireche, Nasca Octavian Paul - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include - -#include "config.h" -#include "alu.h" -#include "alFilter.h" -#include "alError.h" -#include "alMain.h" -#include "alAuxEffectSlot.h" - - -/* Auto-wah is simply a low-pass filter with a cutoff frequency that shifts up - * or down depending on the input signal, and a resonant peak at the cutoff. - * - * Currently, we assume a cutoff frequency range of 500hz (no amplitude) to - * 3khz (peak gain). Peak gain is assumed to be in normalized scale. - */ - -typedef struct ALautowahState { - DERIVE_FROM_TYPE(ALeffectState); - - /* Effect gains for each channel */ - ALfloat Gain[MaxChannels]; - - /* Effect parameters */ - ALfloat AttackRate; - ALfloat ReleaseRate; - ALfloat Resonance; - ALfloat PeakGain; - ALfloat GainCtrl; - ALfloat Frequency; - - /* Samples processing */ - ALfilterState LowPass; -} ALautowahState; - -static ALvoid ALautowahState_Destruct(ALautowahState *UNUSED(state)) -{ -} - -static ALboolean ALautowahState_deviceUpdate(ALautowahState *state, ALCdevice *device) -{ - state->Frequency = (ALfloat)device->Frequency; - return AL_TRUE; -} - -static ALvoid ALautowahState_update(ALautowahState *state, ALCdevice *device, const ALeffectslot *slot) -{ - ALfloat attackTime, releaseTime; - ALfloat gain; - - attackTime = slot->EffectProps.Autowah.AttackTime * state->Frequency; - releaseTime = slot->EffectProps.Autowah.ReleaseTime * state->Frequency; - - state->AttackRate = powf(1.0f/GAIN_SILENCE_THRESHOLD, 1.0f/attackTime); - state->ReleaseRate = powf(GAIN_SILENCE_THRESHOLD/1.0f, 1.0f/releaseTime); - state->PeakGain = slot->EffectProps.Autowah.PeakGain; - state->Resonance = slot->EffectProps.Autowah.Resonance; - - gain = sqrtf(1.0f / device->NumChan) * slot->Gain; - SetGains(device, gain, state->Gain); -} - -static ALvoid ALautowahState_process(ALautowahState *state, ALuint SamplesToDo, const ALfloat *SamplesIn, ALfloat (*SamplesOut)[BUFFERSIZE]) -{ - ALuint it, kt; - ALuint base; - - for(base = 0;base < SamplesToDo;) - { - ALfloat temps[64]; - ALuint td = minu(SamplesToDo-base, 64); - ALfloat gain = state->GainCtrl; - - for(it = 0;it < td;it++) - { - ALfloat smp = SamplesIn[it+base]; - ALfloat alpha, w0; - ALfloat amplitude; - ALfloat cutoff; - - /* Similar to compressor, we get the current amplitude of the - * incoming signal, and attack or release to reach it. */ - amplitude = fabsf(smp); - if(amplitude > gain) - gain = minf(gain*state->AttackRate, amplitude); - else if(amplitude < gain) - gain = maxf(gain*state->ReleaseRate, amplitude); - gain = maxf(gain, GAIN_SILENCE_THRESHOLD); - - /* FIXME: What range does the filter cover? */ - cutoff = lerp(20.0f, 20000.0f, minf(gain/state->PeakGain, 1.0f)); - - /* The code below is like calling ALfilterState_setParams with - * ALfilterType_LowPass. However, instead of passing a bandwidth, - * we use the resonance property for Q. This also inlines the call. - */ - w0 = F_2PI * cutoff / state->Frequency; - - /* FIXME: Resonance controls the resonant peak, or Q. How? Not sure - * that Q = resonance*0.1. */ - alpha = sinf(w0) / (2.0f * state->Resonance*0.1f); - state->LowPass.b[0] = (1.0f - cosf(w0)) / 2.0f; - state->LowPass.b[1] = 1.0f - cosf(w0); - state->LowPass.b[2] = (1.0f - cosf(w0)) / 2.0f; - state->LowPass.a[0] = 1.0f + alpha; - state->LowPass.a[1] = -2.0f * cosf(w0); - state->LowPass.a[2] = 1.0f - alpha; - - state->LowPass.b[2] /= state->LowPass.a[0]; - state->LowPass.b[1] /= state->LowPass.a[0]; - state->LowPass.b[0] /= state->LowPass.a[0]; - state->LowPass.a[2] /= state->LowPass.a[0]; - state->LowPass.a[1] /= state->LowPass.a[0]; - state->LowPass.a[0] /= state->LowPass.a[0]; - - temps[it] = ALfilterState_processSingle(&state->LowPass, smp); - } - state->GainCtrl = gain; - - for(kt = 0;kt < MaxChannels;kt++) - { - ALfloat gain = state->Gain[kt]; - if(!(gain > GAIN_SILENCE_THRESHOLD)) - continue; - - for(it = 0;it < td;it++) - SamplesOut[kt][base+it] += gain * temps[it]; - } - - base += td; - } -} - -DECLARE_DEFAULT_ALLOCATORS(ALautowahState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALautowahState); - - -typedef struct ALautowahStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALautowahStateFactory; - -static ALeffectState *ALautowahStateFactory_create(ALautowahStateFactory *UNUSED(factory)) -{ - ALautowahState *state; - - state = ALautowahState_New(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALautowahState, ALeffectState, state); - - state->AttackRate = 1.0f; - state->ReleaseRate = 1.0f; - state->Resonance = 2.0f; - state->PeakGain = 1.0f; - state->GainCtrl = 1.0f; - - ALfilterState_clear(&state->LowPass); - - return STATIC_CAST(ALeffectState, state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALautowahStateFactory); - -ALeffectStateFactory *ALautowahStateFactory_getFactory(void) -{ - static ALautowahStateFactory AutowahFactory = { { GET_VTABLE2(ALautowahStateFactory, ALeffectStateFactory) } }; - - return STATIC_CAST(ALeffectStateFactory, &AutowahFactory); -} - - -void ALautowah_setParami(ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALautowah_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALautowah_setParami(effect, context, param, vals[0]); -} -void ALautowah_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_AUTOWAH_ATTACK_TIME: - if(!(val >= AL_AUTOWAH_MIN_ATTACK_TIME && val <= AL_AUTOWAH_MAX_ATTACK_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.AttackTime = val; - break; - - case AL_AUTOWAH_RELEASE_TIME: - if(!(val >= AL_AUTOWAH_MIN_RELEASE_TIME && val <= AL_AUTOWAH_MAX_RELEASE_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.ReleaseTime = val; - break; - - case AL_AUTOWAH_RESONANCE: - if(!(val >= AL_AUTOWAH_MIN_RESONANCE && val <= AL_AUTOWAH_MAX_RESONANCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.Resonance = val; - break; - - case AL_AUTOWAH_PEAK_GAIN: - if(!(val >= AL_AUTOWAH_MIN_PEAK_GAIN && val <= AL_AUTOWAH_MAX_PEAK_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Autowah.PeakGain = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALautowah_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALautowah_setParamf(effect, context, param, vals[0]); -} - -void ALautowah_getParami(const ALeffect *UNUSED(effect), ALCcontext *context, ALenum UNUSED(param), ALint *UNUSED(val)) -{ SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); } -void ALautowah_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALautowah_getParami(effect, context, param, vals); -} -void ALautowah_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_AUTOWAH_ATTACK_TIME: - *val = props->Autowah.AttackTime; - break; - - case AL_AUTOWAH_RELEASE_TIME: - *val = props->Autowah.ReleaseTime; - break; - - case AL_AUTOWAH_RESONANCE: - *val = props->Autowah.Resonance; - break; - - case AL_AUTOWAH_PEAK_GAIN: - *val = props->Autowah.PeakGain; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALautowah_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALautowah_getParamf(effect, context, param, vals); -} - -DEFINE_ALEFFECT_VTABLE(ALautowah); diff --git a/love/src/jni/openal-soft-1.17.0/Alc/effects/reverb.c b/love/src/jni/openal-soft-1.17.0/Alc/effects/reverb.c deleted file mode 100644 index 245aed41..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/effects/reverb.c +++ /dev/null @@ -1,1779 +0,0 @@ -/** - * Reverb for the OpenAL cross platform audio library - * Copyright (C) 2008-2009 by Christopher Fitzgerald. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include "alMain.h" -#include "alu.h" -#include "alAuxEffectSlot.h" -#include "alEffect.h" -#include "alFilter.h" -#include "alError.h" - - -typedef struct DelayLine -{ - // The delay lines use sample lengths that are powers of 2 to allow the - // use of bit-masking instead of a modulus for wrapping. - ALuint Mask; - ALfloat *Line; -} DelayLine; - -typedef struct ALreverbState { - DERIVE_FROM_TYPE(ALeffectState); - - ALboolean IsEax; - - // All delay lines are allocated as a single buffer to reduce memory - // fragmentation and management code. - ALfloat *SampleBuffer; - ALuint TotalSamples; - - // Master effect filters - ALfilterState LpFilter; - ALfilterState HpFilter; // EAX only - - struct { - // Modulator delay line. - DelayLine Delay; - - // The vibrato time is tracked with an index over a modulus-wrapped - // range (in samples). - ALuint Index; - ALuint Range; - - // The depth of frequency change (also in samples) and its filter. - ALfloat Depth; - ALfloat Coeff; - ALfloat Filter; - } Mod; - - // Initial effect delay. - DelayLine Delay; - // The tap points for the initial delay. First tap goes to early - // reflections, the last to late reverb. - ALuint DelayTap[2]; - - struct { - // Output gain for early reflections. - ALfloat Gain; - - // Early reflections are done with 4 delay lines. - ALfloat Coeff[4]; - DelayLine Delay[4]; - ALuint Offset[4]; - - // The gain for each output channel based on 3D panning (only for the - // EAX path). - ALfloat PanGain[MaxChannels]; - } Early; - - // Decorrelator delay line. - DelayLine Decorrelator; - // There are actually 4 decorrelator taps, but the first occurs at the - // initial sample. - ALuint DecoTap[3]; - - struct { - // Output gain for late reverb. - ALfloat Gain; - - // Attenuation to compensate for the modal density and decay rate of - // the late lines. - ALfloat DensityGain; - - // The feed-back and feed-forward all-pass coefficient. - ALfloat ApFeedCoeff; - - // Mixing matrix coefficient. - ALfloat MixCoeff; - - // Late reverb has 4 parallel all-pass filters. - ALfloat ApCoeff[4]; - DelayLine ApDelay[4]; - ALuint ApOffset[4]; - - // In addition to 4 cyclical delay lines. - ALfloat Coeff[4]; - DelayLine Delay[4]; - ALuint Offset[4]; - - // The cyclical delay lines are 1-pole low-pass filtered. - ALfloat LpCoeff[4]; - ALfloat LpSample[4]; - - // The gain for each output channel based on 3D panning (only for the - // EAX path). - ALfloat PanGain[MaxChannels]; - } Late; - - struct { - // Attenuation to compensate for the modal density and decay rate of - // the echo line. - ALfloat DensityGain; - - // Echo delay and all-pass lines. - DelayLine Delay; - DelayLine ApDelay; - - ALfloat Coeff; - ALfloat ApFeedCoeff; - ALfloat ApCoeff; - - ALuint Offset; - ALuint ApOffset; - - // The echo line is 1-pole low-pass filtered. - ALfloat LpCoeff; - ALfloat LpSample; - - // Echo mixing coefficients. - ALfloat MixCoeff[2]; - } Echo; - - // The current read offset for all delay lines. - ALuint Offset; - - // 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]; -} ALreverbState; - -/* This is a user config option for modifying the overall output of the reverb - * effect. - */ -ALfloat ReverbBoost = 1.0f; - -/* Specifies whether to use a standard reverb effect in place of EAX reverb */ -ALboolean EmulateEAXReverb = AL_FALSE; - -/* This coefficient is used to define the maximum frequency range controlled - * by the modulation depth. The current value of 0.1 will allow it to swing - * from 0.9x to 1.1x. This value must be below 1. At 1 it will cause the - * sampler to stall on the downswing, and above 1 it will cause it to sample - * backwards. - */ -static const ALfloat MODULATION_DEPTH_COEFF = 0.1f; - -/* A filter is used to avoid the terrible distortion caused by changing - * modulation time and/or depth. To be consistent across different sample - * rates, the coefficient must be raised to a constant divided by the sample - * rate: coeff^(constant / rate). - */ -static const ALfloat MODULATION_FILTER_COEFF = 0.048f; -static const ALfloat MODULATION_FILTER_CONST = 100000.0f; - -// When diffusion is above 0, an all-pass filter is used to take the edge off -// the echo effect. It uses the following line length (in seconds). -static const ALfloat ECHO_ALLPASS_LENGTH = 0.0133f; - -// Input into the late reverb is decorrelated between four channels. Their -// timings are dependent on a fraction and multiplier. See the -// UpdateDecorrelator() routine for the calculations involved. -static const ALfloat DECO_FRACTION = 0.15f; -static const ALfloat DECO_MULTIPLIER = 2.0f; - -// All delay line lengths are specified in seconds. - -// The lengths of the early delay lines. -static const ALfloat EARLY_LINE_LENGTH[4] = -{ - 0.0015f, 0.0045f, 0.0135f, 0.0405f -}; - -// The lengths of the late all-pass delay lines. -static const ALfloat ALLPASS_LINE_LENGTH[4] = -{ - 0.0151f, 0.0167f, 0.0183f, 0.0200f, -}; - -// The lengths of the late cyclical delay lines. -static const ALfloat LATE_LINE_LENGTH[4] = -{ - 0.0211f, 0.0311f, 0.0461f, 0.0680f -}; - -// The late cyclical delay lines have a variable length dependent on the -// effect's density parameter (inverted for some reason) and this multiplier. -static const ALfloat LATE_LINE_MULTIPLIER = 4.0f; - - -// Basic delay line input/output routines. -static inline ALfloat DelayLineOut(DelayLine *Delay, ALuint offset) -{ - return Delay->Line[offset&Delay->Mask]; -} - -static inline ALvoid DelayLineIn(DelayLine *Delay, ALuint offset, ALfloat in) -{ - Delay->Line[offset&Delay->Mask] = in; -} - -// Attenuated delay line output routine. -static inline ALfloat AttenuatedDelayLineOut(DelayLine *Delay, ALuint offset, ALfloat coeff) -{ - return coeff * Delay->Line[offset&Delay->Mask]; -} - -// Basic attenuated all-pass input/output routine. -static inline ALfloat AllpassInOut(DelayLine *Delay, ALuint outOffset, ALuint inOffset, ALfloat in, ALfloat feedCoeff, ALfloat coeff) -{ - ALfloat out, feed; - - out = DelayLineOut(Delay, outOffset); - feed = feedCoeff * in; - DelayLineIn(Delay, inOffset, (feedCoeff * (out - feed)) + in); - - // The time-based attenuation is only applied to the delay output to - // keep it from affecting the feed-back path (which is already controlled - // by the all-pass feed coefficient). - return (coeff * out) - feed; -} - -// Given an input sample, this function produces modulation for the late -// reverb. -static inline ALfloat EAXModulation(ALreverbState *State, ALfloat in) -{ - ALfloat sinus, frac; - ALuint offset; - ALfloat out0, out1; - - // 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 - cosf(F_2PI * 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 - // small parameter changes. - State->Mod.Filter = lerp(State->Mod.Filter, State->Mod.Depth, - State->Mod.Coeff); - - // Calculate the read offset and fraction between it and the next sample. - frac = (1.0f + (State->Mod.Filter * sinus)); - offset = fastf2u(frac); - frac -= offset; - - // Get the two samples crossed by the offset, and feed the delay line - // with the next input sample. - out0 = DelayLineOut(&State->Mod.Delay, State->Offset - offset); - out1 = DelayLineOut(&State->Mod.Delay, State->Offset - offset - 1); - DelayLineIn(&State->Mod.Delay, State->Offset, in); - - // Step the modulation index forward, keeping it bound to its range. - State->Mod.Index = (State->Mod.Index + 1) % State->Mod.Range; - - // The output is obtained by linearly interpolating the two samples that - // were acquired above. - return lerp(out0, out1, frac); -} - -// Delay line output routine for early reflections. -static inline ALfloat EarlyDelayLineOut(ALreverbState *State, ALuint index) -{ - return AttenuatedDelayLineOut(&State->Early.Delay[index], - State->Offset - State->Early.Offset[index], - State->Early.Coeff[index]); -} - -// Given an input sample, this function produces four-channel output for the -// early reflections. -static inline ALvoid EarlyReflection(ALreverbState *State, ALfloat in, ALfloat *restrict out) -{ - ALfloat d[4], v, f[4]; - - // Obtain the decayed results of each early delay line. - d[0] = EarlyDelayLineOut(State, 0); - d[1] = EarlyDelayLineOut(State, 1); - d[2] = EarlyDelayLineOut(State, 2); - d[3] = EarlyDelayLineOut(State, 3); - - /* The following uses a lossless scattering junction from waveguide - * theory. It actually amounts to a householder mixing matrix, which - * will produce a maximally diffuse response, and means this can probably - * be considered a simple feed-back delay network (FDN). - * N - * --- - * \ - * v = 2/N / d_i - * --- - * i=1 - */ - v = (d[0] + d[1] + d[2] + d[3]) * 0.5f; - // The junction is loaded with the input here. - v += in; - - // Calculate the feed values for the delay lines. - f[0] = v - d[0]; - f[1] = v - d[1]; - f[2] = v - d[2]; - f[3] = v - d[3]; - - // Re-feed the delay lines. - DelayLineIn(&State->Early.Delay[0], State->Offset, f[0]); - DelayLineIn(&State->Early.Delay[1], State->Offset, f[1]); - DelayLineIn(&State->Early.Delay[2], State->Offset, f[2]); - DelayLineIn(&State->Early.Delay[3], State->Offset, f[3]); - - // Output the results of the junction for all four channels. - out[0] = State->Early.Gain * f[0]; - out[1] = State->Early.Gain * f[1]; - out[2] = State->Early.Gain * f[2]; - out[3] = State->Early.Gain * f[3]; -} - -// All-pass input/output routine for late reverb. -static inline ALfloat LateAllPassInOut(ALreverbState *State, ALuint index, ALfloat in) -{ - return AllpassInOut(&State->Late.ApDelay[index], - State->Offset - State->Late.ApOffset[index], - State->Offset, in, State->Late.ApFeedCoeff, - State->Late.ApCoeff[index]); -} - -// Delay line output routine for late reverb. -static inline ALfloat LateDelayLineOut(ALreverbState *State, ALuint index) -{ - return AttenuatedDelayLineOut(&State->Late.Delay[index], - State->Offset - State->Late.Offset[index], - State->Late.Coeff[index]); -} - -// Low-pass filter input/output routine for late reverb. -static inline ALfloat LateLowPassInOut(ALreverbState *State, ALuint index, ALfloat in) -{ - in = lerp(in, State->Late.LpSample[index], State->Late.LpCoeff[index]); - State->Late.LpSample[index] = in; - return in; -} - -// Given four decorrelated input samples, this function produces four-channel -// output for the late reverb. -static inline ALvoid LateReverb(ALreverbState *State, const ALfloat *restrict in, ALfloat *restrict out) -{ - ALfloat d[4], f[4]; - - // Obtain the decayed results of the cyclical delay lines, and add the - // corresponding input channels. Then pass the results through the - // low-pass filters. - - // This is where the feed-back cycles from line 0 to 1 to 3 to 2 and back - // to 0. - d[0] = LateLowPassInOut(State, 2, in[2] + LateDelayLineOut(State, 2)); - d[1] = LateLowPassInOut(State, 0, in[0] + LateDelayLineOut(State, 0)); - d[2] = LateLowPassInOut(State, 3, in[3] + LateDelayLineOut(State, 3)); - d[3] = LateLowPassInOut(State, 1, in[1] + LateDelayLineOut(State, 1)); - - // To help increase diffusion, run each line through an all-pass filter. - // When there is no diffusion, the shortest all-pass filter will feed the - // shortest delay line. - d[0] = LateAllPassInOut(State, 0, d[0]); - d[1] = LateAllPassInOut(State, 1, d[1]); - d[2] = LateAllPassInOut(State, 2, d[2]); - d[3] = LateAllPassInOut(State, 3, d[3]); - - /* Late reverb is done with a modified feed-back delay network (FDN) - * topology. Four input lines are each fed through their own all-pass - * filter and then into the mixing matrix. The four outputs of the - * mixing matrix are then cycled back to the inputs. Each output feeds - * a different input to form a circlular feed cycle. - * - * The mixing matrix used is a 4D skew-symmetric rotation matrix derived - * using a single unitary rotational parameter: - * - * [ d, a, b, c ] 1 = a^2 + b^2 + c^2 + d^2 - * [ -a, d, c, -b ] - * [ -b, -c, d, a ] - * [ -c, b, -a, d ] - * - * The rotation is constructed from the effect's diffusion parameter, - * yielding: 1 = x^2 + 3 y^2; where a, b, and c are the coefficient y - * with differing signs, and d is the coefficient x. The matrix is thus: - * - * [ x, y, -y, y ] n = sqrt(matrix_order - 1) - * [ -y, x, y, y ] t = diffusion_parameter * atan(n) - * [ y, -y, x, y ] x = cos(t) - * [ -y, -y, -y, x ] y = sin(t) / n - * - * To reduce the number of multiplies, the x coefficient is applied with - * the cyclical delay line coefficients. Thus only the y coefficient is - * applied when mixing, and is modified to be: y / x. - */ - f[0] = d[0] + (State->Late.MixCoeff * ( d[1] + -d[2] + d[3])); - f[1] = d[1] + (State->Late.MixCoeff * (-d[0] + d[2] + d[3])); - f[2] = d[2] + (State->Late.MixCoeff * ( d[0] + -d[1] + d[3])); - f[3] = d[3] + (State->Late.MixCoeff * (-d[0] + -d[1] + -d[2] )); - - // Output the results of the matrix for all four channels, attenuated by - // the late reverb gain (which is attenuated by the 'x' mix coefficient). - out[0] = State->Late.Gain * f[0]; - out[1] = State->Late.Gain * f[1]; - out[2] = State->Late.Gain * f[2]; - out[3] = State->Late.Gain * f[3]; - - // Re-feed the cyclical delay lines. - DelayLineIn(&State->Late.Delay[0], State->Offset, f[0]); - DelayLineIn(&State->Late.Delay[1], State->Offset, f[1]); - DelayLineIn(&State->Late.Delay[2], State->Offset, f[2]); - DelayLineIn(&State->Late.Delay[3], State->Offset, f[3]); -} - -// Given an input sample, this function mixes echo into the four-channel late -// reverb. -static inline ALvoid EAXEcho(ALreverbState *State, ALfloat in, ALfloat *restrict late) -{ - ALfloat out, feed; - - // Get the latest attenuated echo sample for output. - feed = AttenuatedDelayLineOut(&State->Echo.Delay, - State->Offset - State->Echo.Offset, - State->Echo.Coeff); - - // Mix the output into the late reverb channels. - out = State->Echo.MixCoeff[0] * feed; - late[0] = (State->Echo.MixCoeff[1] * late[0]) + out; - late[1] = (State->Echo.MixCoeff[1] * late[1]) + out; - late[2] = (State->Echo.MixCoeff[1] * late[2]) + out; - late[3] = (State->Echo.MixCoeff[1] * late[3]) + out; - - // Mix the energy-attenuated input with the output and pass it through - // the echo low-pass filter. - feed += State->Echo.DensityGain * in; - feed = lerp(feed, State->Echo.LpSample, State->Echo.LpCoeff); - State->Echo.LpSample = feed; - - // Then the echo all-pass filter. - feed = AllpassInOut(&State->Echo.ApDelay, - State->Offset - State->Echo.ApOffset, - State->Offset, feed, State->Echo.ApFeedCoeff, - State->Echo.ApCoeff); - - // Feed the delay with the mixed and filtered sample. - DelayLineIn(&State->Echo.Delay, State->Offset, feed); -} - -// Perform the non-EAX reverb pass on a given input sample, resulting in -// four-channel output. -static inline ALvoid VerbPass(ALreverbState *State, ALfloat in, ALfloat *restrict out) -{ - ALfloat feed, late[4], taps[4]; - - // Filter the incoming sample. - in = ALfilterState_processSingle(&State->LpFilter, in); - - // Feed the initial delay line. - DelayLineIn(&State->Delay, State->Offset, in); - - // Calculate the early reflection from the first delay tap. - in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]); - EarlyReflection(State, in, out); - - // Feed the decorrelator from the energy-attenuated output of the second - // delay tap. - in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]); - feed = in * State->Late.DensityGain; - DelayLineIn(&State->Decorrelator, State->Offset, feed); - - // Calculate the late reverb from the decorrelator taps. - taps[0] = feed; - taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]); - taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]); - 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(ALreverbState *State, ALfloat in, ALfloat *restrict early, ALfloat *restrict late) -{ - ALfloat feed, taps[4]; - - // Low-pass filter the incoming sample. - in = ALfilterState_processSingle(&State->LpFilter, in); - in = ALfilterState_processSingle(&State->HpFilter, in); - - // Perform any modulation on the input. - in = EAXModulation(State, in); - - // Feed the initial delay line. - DelayLineIn(&State->Delay, State->Offset, in); - - // Calculate the early reflection from the first delay tap. - in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[0]); - EarlyReflection(State, in, early); - - // Feed the decorrelator from the energy-attenuated output of the second - // delay tap. - in = DelayLineOut(&State->Delay, State->Offset - State->DelayTap[1]); - feed = in * State->Late.DensityGain; - DelayLineIn(&State->Decorrelator, State->Offset, feed); - - // Calculate the late reverb from the decorrelator taps. - taps[0] = feed; - taps[1] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[0]); - taps[2] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[1]); - taps[3] = DelayLineOut(&State->Decorrelator, State->Offset - State->DecoTap[2]); - LateReverb(State, taps, late); - - // Calculate and mix in any echo. - EAXEcho(State, in, late); - - // Step all delays forward one sample. - State->Offset++; -} - -static ALvoid ALreverbState_processStandard(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - ALfloat (*restrict out)[4] = State->ReverbSamples; - ALuint index, c; - - /* Process reverb for these samples. */ - for(index = 0;index < SamplesToDo;index++) - VerbPass(State, SamplesIn[index], out[index]); - - for(c = 0;c < MaxChannels;c++) - { - ALfloat gain = State->Gain[c]; - if(!(gain > GAIN_SILENCE_THRESHOLD)) - continue; - - for(index = 0;index < SamplesToDo;index++) - SamplesOut[c][index] += gain * out[index][c&3]; - } -} - -static ALvoid ALreverbState_processEax(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - ALfloat (*restrict early)[4] = State->EarlySamples; - ALfloat (*restrict late)[4] = State->ReverbSamples; - ALuint index, c; - - /* Process reverb for these samples. */ - for(index = 0;index < SamplesToDo;index++) - EAXVerbPass(State, SamplesIn[index], early[index], late[index]); - - for(c = 0;c < MaxChannels;c++) - { - ALfloat earlyGain, lateGain; - - earlyGain = State->Early.PanGain[c]; - if(earlyGain > GAIN_SILENCE_THRESHOLD) - { - for(index = 0;index < SamplesToDo;index++) - SamplesOut[c][index] += earlyGain*early[index][c&3]; - } - lateGain = State->Late.PanGain[c]; - if(lateGain > GAIN_SILENCE_THRESHOLD) - { - for(index = 0;index < SamplesToDo;index++) - SamplesOut[c][index] += lateGain*late[index][c&3]; - } - } -} - -static ALvoid ALreverbState_process(ALreverbState *State, ALuint SamplesToDo, const ALfloat *restrict SamplesIn, ALfloat (*restrict SamplesOut)[BUFFERSIZE]) -{ - if(State->IsEax) - ALreverbState_processEax(State, SamplesToDo, SamplesIn, SamplesOut); - else - ALreverbState_processStandard(State, SamplesToDo, SamplesIn, SamplesOut); -} - -// Given the allocated sample buffer, this function updates each delay line -// offset. -static inline ALvoid RealizeLineOffset(ALfloat *sampleBuffer, DelayLine *Delay) -{ - Delay->Line = &sampleBuffer[(ALintptrEXT)Delay->Line]; -} - -// Calculate the length of a delay line and store its mask and offset. -static ALuint CalcLineLength(ALfloat length, ALintptrEXT offset, ALuint frequency, DelayLine *Delay) -{ - ALuint samples; - - // All line lengths are powers of 2, calculated from their lengths, with - // an additional sample in case of rounding errors. - samples = NextPowerOf2(fastf2u(length * frequency) + 1); - // All lines share a single sample buffer. - Delay->Mask = samples - 1; - Delay->Line = (ALfloat*)offset; - // Return the sample count for accumulation. - return samples; -} - -/* Calculates the delay line metrics and allocates the shared sample buffer - * for all lines given the sample rate (frequency). If an allocation failure - * occurs, it returns AL_FALSE. - */ -static ALboolean AllocLines(ALuint frequency, ALreverbState *State) -{ - ALuint totalSamples, index; - ALfloat length; - ALfloat *newBuffer = NULL; - - // All delay line lengths are calculated to accomodate the full range of - // lengths given their respective paramters. - totalSamples = 0; - - /* The modulator's line length is calculated from the maximum modulation - * time and depth coefficient, and halfed for the low-to-high frequency - * swing. An additional sample is added to keep it stable when there is no - * modulation. - */ - length = (AL_EAXREVERB_MAX_MODULATION_TIME*MODULATION_DEPTH_COEFF/2.0f) + - (1.0f / frequency); - totalSamples += CalcLineLength(length, totalSamples, frequency, - &State->Mod.Delay); - - // The initial delay is the sum of the reflections and late reverb - // delays. - length = AL_EAXREVERB_MAX_REFLECTIONS_DELAY + - AL_EAXREVERB_MAX_LATE_REVERB_DELAY; - totalSamples += CalcLineLength(length, totalSamples, frequency, - &State->Delay); - - // The early reflection lines. - for(index = 0;index < 4;index++) - totalSamples += CalcLineLength(EARLY_LINE_LENGTH[index], totalSamples, - frequency, &State->Early.Delay[index]); - - // The decorrelator line is calculated from the lowest reverb density (a - // parameter value of 1). - length = (DECO_FRACTION * DECO_MULTIPLIER * DECO_MULTIPLIER) * - LATE_LINE_LENGTH[0] * (1.0f + LATE_LINE_MULTIPLIER); - totalSamples += CalcLineLength(length, totalSamples, frequency, - &State->Decorrelator); - - // The late all-pass lines. - for(index = 0;index < 4;index++) - totalSamples += CalcLineLength(ALLPASS_LINE_LENGTH[index], totalSamples, - frequency, &State->Late.ApDelay[index]); - - // The late delay lines are calculated from the lowest reverb density. - for(index = 0;index < 4;index++) - { - length = LATE_LINE_LENGTH[index] * (1.0f + LATE_LINE_MULTIPLIER); - totalSamples += CalcLineLength(length, totalSamples, frequency, - &State->Late.Delay[index]); - } - - // The echo all-pass and delay lines. - totalSamples += CalcLineLength(ECHO_ALLPASS_LENGTH, totalSamples, - frequency, &State->Echo.ApDelay); - totalSamples += CalcLineLength(AL_EAXREVERB_MAX_ECHO_TIME, totalSamples, - frequency, &State->Echo.Delay); - - if(totalSamples != State->TotalSamples) - { - TRACE("New reverb buffer length: %u samples (%f sec)\n", totalSamples, totalSamples/(float)frequency); - newBuffer = realloc(State->SampleBuffer, sizeof(ALfloat) * totalSamples); - if(newBuffer == NULL) - return AL_FALSE; - State->SampleBuffer = newBuffer; - State->TotalSamples = totalSamples; - } - - // Update all delays to reflect the new sample buffer. - RealizeLineOffset(State->SampleBuffer, &State->Delay); - RealizeLineOffset(State->SampleBuffer, &State->Decorrelator); - for(index = 0;index < 4;index++) - { - RealizeLineOffset(State->SampleBuffer, &State->Early.Delay[index]); - RealizeLineOffset(State->SampleBuffer, &State->Late.ApDelay[index]); - RealizeLineOffset(State->SampleBuffer, &State->Late.Delay[index]); - } - RealizeLineOffset(State->SampleBuffer, &State->Mod.Delay); - RealizeLineOffset(State->SampleBuffer, &State->Echo.ApDelay); - RealizeLineOffset(State->SampleBuffer, &State->Echo.Delay); - - // Clear the sample buffer. - for(index = 0;index < State->TotalSamples;index++) - State->SampleBuffer[index] = 0.0f; - - return AL_TRUE; -} - -static ALboolean ALreverbState_deviceUpdate(ALreverbState *State, ALCdevice *Device) -{ - ALuint frequency = Device->Frequency, index; - - // Allocate the delay lines. - if(!AllocLines(frequency, State)) - return AL_FALSE; - - // Calculate the modulation filter coefficient. Notice that the exponent - // 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 = 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. - for(index = 0;index < 4;index++) - { - State->Early.Offset[index] = fastf2u(EARLY_LINE_LENGTH[index] * - frequency); - State->Late.ApOffset[index] = fastf2u(ALLPASS_LINE_LENGTH[index] * - frequency); - } - - // The echo all-pass filter line length is static, so its offset only - // needs to be calculated once. - State->Echo.ApOffset = fastf2u(ECHO_ALLPASS_LENGTH * frequency); - - return AL_TRUE; -} - -// Calculate a decay coefficient given the length of each cycle and the time -// until the decay reaches -60 dB. -static inline ALfloat CalcDecayCoeff(ALfloat length, ALfloat 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 log10f(coeff) * decayTime / log10f(0.001f)/*-60 dB*/; -} - -// Calculate an attenuation to be applied to the input of any echo models to -// compensate for modal density and decay time. -static inline ALfloat CalcDensityGain(ALfloat a) -{ - /* The energy of a signal can be obtained by finding the area under the - * squared signal. This takes the form of Sum(x_n^2), where x is the - * amplitude for the sample n. - * - * Decaying feedback matches exponential decay of the form Sum(a^n), - * where a is the attenuation coefficient, and n is the sample. The area - * under this decay curve can be calculated as: 1 / (1 - a). - * - * Modifying the above equation to find the squared area under the curve - * (for energy) yields: 1 / (1 - a^2). Input attenuation can then be - * calculated by inverting the square root of this approximation, - * yielding: 1 / sqrt(1 / (1 - a^2)), simplified to: sqrt(1 - a^2). - */ - return sqrtf(1.0f - (a * a)); -} - -// Calculate the mixing matrix coefficients given a diffusion factor. -static inline ALvoid CalcMatrixCoeffs(ALfloat diffusion, ALfloat *x, ALfloat *y) -{ - ALfloat n, t; - - // The matrix is of order 4, so n is sqrt (4 - 1). - n = sqrtf(3.0f); - t = diffusion * atanf(n); - - // Calculate the first mixing matrix coefficient. - *x = cosf(t); - // Calculate the second mixing matrix coefficient. - *y = sinf(t) / n; -} - -// Calculate the limited HF ratio for use with the late reverb low-pass -// filters. -static ALfloat CalcLimitedHfRatio(ALfloat hfRatio, ALfloat airAbsorptionGainHF, ALfloat decayTime) -{ - ALfloat limitRatio; - - /* Find the attenuation due to air absorption in dB (converting delay - * time to meters using the speed of sound). Then reversing the decay - * equation, solve for HF ratio. The delay length is cancelled out of - * the equation, so it can be calculated once for all lines. - */ - limitRatio = 1.0f / (CalcDecayLength(airAbsorptionGainHF, decayTime) * - SPEEDOFSOUNDMETRESPERSEC); - /* Using the limit calculated above, apply the upper bound to the HF - * ratio. Also need to limit the result to a minimum of 0.1, just like the - * HF ratio parameter. */ - return clampf(limitRatio, 0.1f, hfRatio); -} - -// Calculate the coefficient for a HF (and eventually LF) decay damping -// filter. -static inline ALfloat CalcDampingCoeff(ALfloat hfRatio, ALfloat length, ALfloat decayTime, ALfloat decayCoeff, ALfloat cw) -{ - ALfloat coeff, g; - - // Eventually this should boost the high frequencies when the ratio - // exceeds 1. - coeff = 0.0f; - if (hfRatio < 1.0f) - { - // Calculate the low-pass coefficient by dividing the HF decay - // coefficient by the full decay coefficient. - g = CalcDecayCoeff(length, decayTime * hfRatio) / decayCoeff; - - // Damping is done with a 1-pole filter, so g needs to be squared. - g *= g; - 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); - coeff = (1 - g*cw - sqrtf(2*g*(1-cw) - g*g*(1 - cw*cw))) / - (1 - g); - } - - // Very low decay times will produce minimal output, so apply an - // upper bound to the coefficient. - coeff = minf(coeff, 0.98f); - } - return coeff; -} - -// Update the EAX modulation index, range, and depth. Keep in mind that this -// kind of vibrato is additive and not multiplicative as one may expect. The -// downswing will sound stronger than the upswing. -static ALvoid UpdateModulator(ALfloat modTime, ALfloat modDepth, ALuint frequency, ALreverbState *State) -{ - ALuint range; - - /* Modulation is calculated in two parts. - * - * The modulation time effects the sinus applied to the change in - * frequency. An index out of the current time range (both in samples) - * is incremented each sample. The range is bound to a reasonable - * minimum (1 sample) and when the timing changes, the index is rescaled - * to the new range (to keep the sinus consistent). - */ - range = maxu(fastf2u(modTime*frequency), 1); - State->Mod.Index = (ALuint)(State->Mod.Index * (ALuint64)range / - State->Mod.Range); - State->Mod.Range = range; - - /* The modulation depth effects the amount of frequency change over the - * range of the sinus. It needs to be scaled by the modulation time so - * that a given depth produces a consistent change in frequency over all - * ranges of time. Since the depth is applied to a sinus value, it needs - * to be halfed once for the sinus range and again for the sinus swing - * in time (half of it is spent decreasing the frequency, half is spent - * increasing it). - */ - State->Mod.Depth = modDepth * MODULATION_DEPTH_COEFF * modTime / 2.0f / - 2.0f * frequency; -} - -// Update the offsets for the initial effect delay line. -static ALvoid UpdateDelayLine(ALfloat earlyDelay, ALfloat lateDelay, ALuint frequency, ALreverbState *State) -{ - // Calculate the initial delay taps. - State->DelayTap[0] = fastf2u(earlyDelay * frequency); - State->DelayTap[1] = fastf2u((earlyDelay + lateDelay) * frequency); -} - -// Update the early reflections gain and line coefficients. -static ALvoid UpdateEarlyLines(ALfloat reverbGain, ALfloat earlyGain, ALfloat lateDelay, ALreverbState *State) -{ - ALuint index; - - // Calculate the early reflections gain (from the master effect gain, and - // reflections gain parameters) with a constant attenuation of 0.5. - State->Early.Gain = 0.5f * reverbGain * earlyGain; - - // Calculate the gain (coefficient) for each early delay line using the - // late delay time. This expands the early reflections to the start of - // the late reverb. - for(index = 0;index < 4;index++) - State->Early.Coeff[index] = CalcDecayCoeff(EARLY_LINE_LENGTH[index], - lateDelay); -} - -// Update the offsets for the decorrelator line. -static ALvoid UpdateDecorrelator(ALfloat density, ALuint frequency, ALreverbState *State) -{ - ALuint index; - ALfloat length; - - /* The late reverb inputs are decorrelated to smooth the reverb tail and - * reduce harsh echos. The first tap occurs immediately, while the - * remaining taps are delayed by multiples of a fraction of the smallest - * cyclical delay time. - * - * offset[index] = (FRACTION (MULTIPLIER^index)) smallest_delay - */ - for(index = 0;index < 3;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); - } -} - -// Update the late reverb gains, line lengths, and line coefficients. -static ALvoid UpdateLateLines(ALfloat reverbGain, ALfloat lateGain, ALfloat xMix, ALfloat density, ALfloat decayTime, ALfloat diffusion, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State) -{ - ALfloat length; - ALuint index; - - /* Calculate the late reverb gain (from the master effect gain, and late - * reverb gain parameters). Since the output is tapped prior to the - * application of the next delay line coefficients, this gain needs to be - * attenuated by the 'x' mixing matrix coefficient as well. - */ - State->Late.Gain = reverbGain * lateGain * xMix; - - /* To compensate for changes in modal density and decay time of the late - * reverb signal, the input is attenuated based on the maximal energy of - * the outgoing signal. This approximation is used to keep the apparent - * energy of the signal equal for all ranges of density and decay time. - * - * The average length of the cyclcical delay lines is used to calculate - * the attenuation coefficient. - */ - length = (LATE_LINE_LENGTH[0] + LATE_LINE_LENGTH[1] + - LATE_LINE_LENGTH[2] + LATE_LINE_LENGTH[3]) / 4.0f; - length *= 1.0f + (density * LATE_LINE_MULTIPLIER); - State->Late.DensityGain = CalcDensityGain(CalcDecayCoeff(length, - decayTime)); - - // Calculate the all-pass feed-back and feed-forward coefficient. - State->Late.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f); - - for(index = 0;index < 4;index++) - { - // Calculate the gain (coefficient) for each all-pass line. - State->Late.ApCoeff[index] = CalcDecayCoeff(ALLPASS_LINE_LENGTH[index], - decayTime); - - // Calculate the length (in seconds) of each cyclical delay line. - length = LATE_LINE_LENGTH[index] * (1.0f + (density * - LATE_LINE_MULTIPLIER)); - - // Calculate the delay offset for each cyclical delay line. - State->Late.Offset[index] = fastf2u(length * frequency); - - // Calculate the gain (coefficient) for each cyclical line. - State->Late.Coeff[index] = CalcDecayCoeff(length, decayTime); - - // Calculate the damping coefficient for each low-pass filter. - State->Late.LpCoeff[index] = - CalcDampingCoeff(hfRatio, length, decayTime, - State->Late.Coeff[index], cw); - - // Attenuate the cyclical line coefficients by the mixing coefficient - // (x). - State->Late.Coeff[index] *= xMix; - } -} - -// Update the echo gain, line offset, line coefficients, and mixing -// coefficients. -static ALvoid UpdateEchoLine(ALfloat reverbGain, ALfloat lateGain, ALfloat echoTime, ALfloat decayTime, ALfloat diffusion, ALfloat echoDepth, ALfloat hfRatio, ALfloat cw, ALuint frequency, ALreverbState *State) -{ - // Update the offset and coefficient for the echo delay line. - State->Echo.Offset = fastf2u(echoTime * frequency); - - // Calculate the decay coefficient for the echo line. - State->Echo.Coeff = CalcDecayCoeff(echoTime, decayTime); - - // Calculate the energy-based attenuation coefficient for the echo delay - // line. - State->Echo.DensityGain = CalcDensityGain(State->Echo.Coeff); - - // Calculate the echo all-pass feed coefficient. - State->Echo.ApFeedCoeff = 0.5f * powf(diffusion, 2.0f); - - // Calculate the echo all-pass attenuation coefficient. - State->Echo.ApCoeff = CalcDecayCoeff(ECHO_ALLPASS_LENGTH, decayTime); - - // Calculate the damping coefficient for each low-pass filter. - State->Echo.LpCoeff = CalcDampingCoeff(hfRatio, echoTime, decayTime, - State->Echo.Coeff, cw); - - /* Calculate the echo mixing coefficients. The first is applied to the - * echo itself. The second is used to attenuate the late reverb when - * echo depth is high and diffusion is low, so the echo is slightly - * stronger than the decorrelated echos in the reverb tail. - */ - State->Echo.MixCoeff[0] = reverbGain * lateGain * echoDepth; - State->Echo.MixCoeff[1] = 1.0f - (echoDepth * 0.5f * (1.0f - diffusion)); -} - -// Update the early and late 3D panning gains. -static ALvoid Update3DPanning(const ALCdevice *Device, const ALfloat *ReflectionsPan, const ALfloat *LateReverbPan, ALfloat Gain, ALreverbState *State) -{ - ALfloat earlyPan[3] = { ReflectionsPan[0], ReflectionsPan[1], - ReflectionsPan[2] }; - ALfloat latePan[3] = { LateReverbPan[0], LateReverbPan[1], - LateReverbPan[2] }; - ALfloat ambientGain; - ALfloat dirGain; - ALfloat length; - - Gain *= ReverbBoost; - - /* 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); - - length = earlyPan[0]*earlyPan[0] + earlyPan[1]*earlyPan[1] + earlyPan[2]*earlyPan[2]; - if(length > 1.0f) - { - length = 1.0f / sqrtf(length); - earlyPan[0] *= length; - earlyPan[1] *= length; - earlyPan[2] *= length; - } - length = latePan[0]*latePan[0] + latePan[1]*latePan[1] + latePan[2]*latePan[2]; - if(length > 1.0f) - { - length = 1.0f / sqrtf(length); - latePan[0] *= length; - latePan[1] *= length; - latePan[2] *= length; - } - - dirGain = sqrtf(earlyPan[0]*earlyPan[0] + earlyPan[2]*earlyPan[2]); - ComputeAngleGains(Device, atan2f(earlyPan[0], earlyPan[2]), (1.0f-dirGain)*F_PI, - lerp(ambientGain, 1.0f, dirGain) * Gain, State->Early.PanGain); - - dirGain = sqrtf(latePan[0]*latePan[0] + latePan[2]*latePan[2]); - ComputeAngleGains(Device, atan2f(latePan[0], latePan[2]), (1.0f-dirGain)*F_PI, - lerp(ambientGain, 1.0f, dirGain) * Gain, State->Late.PanGain); -} - -static ALvoid ALreverbState_update(ALreverbState *State, ALCdevice *Device, const ALeffectslot *Slot) -{ - ALuint frequency = Device->Frequency; - ALfloat lfscale, hfscale, hfRatio; - ALfloat cw, x, y; - - if(Slot->EffectType == AL_EFFECT_EAXREVERB && !EmulateEAXReverb) - State->IsEax = AL_TRUE; - else if(Slot->EffectType == AL_EFFECT_REVERB || EmulateEAXReverb) - State->IsEax = AL_FALSE; - - // Calculate the master low-pass filter (from the master effect HF gain). - if(State->IsEax) - { - hfscale = Slot->EffectProps.Reverb.HFReference / frequency; - ALfilterState_setParams(&State->LpFilter, ALfilterType_HighShelf, - Slot->EffectProps.Reverb.GainHF, - hfscale, 0.0f); - lfscale = Slot->EffectProps.Reverb.LFReference / frequency; - ALfilterState_setParams(&State->HpFilter, ALfilterType_LowShelf, - Slot->EffectProps.Reverb.GainLF, - lfscale, 0.0f); - } - else - { - hfscale = LOWPASSFREQREF / frequency; - ALfilterState_setParams(&State->LpFilter, ALfilterType_HighShelf, - Slot->EffectProps.Reverb.GainHF, - hfscale, 0.0f); - } - - if(State->IsEax) - { - // Update the modulator line. - UpdateModulator(Slot->EffectProps.Reverb.ModulationTime, - Slot->EffectProps.Reverb.ModulationDepth, - frequency, State); - } - - // Update the initial effect delay. - UpdateDelayLine(Slot->EffectProps.Reverb.ReflectionsDelay, - Slot->EffectProps.Reverb.LateReverbDelay, - frequency, State); - - // Update the early lines. - UpdateEarlyLines(Slot->EffectProps.Reverb.Gain, - Slot->EffectProps.Reverb.ReflectionsGain, - Slot->EffectProps.Reverb.LateReverbDelay, State); - - // Update the decorrelator. - UpdateDecorrelator(Slot->EffectProps.Reverb.Density, frequency, State); - - // Get the mixing matrix coefficients (x and y). - CalcMatrixCoeffs(Slot->EffectProps.Reverb.Diffusion, &x, &y); - // Then divide x into y to simplify the matrix calculation. - State->Late.MixCoeff = y / x; - - // If the HF limit parameter is flagged, calculate an appropriate limit - // based on the air absorption parameter. - hfRatio = Slot->EffectProps.Reverb.DecayHFRatio; - if(Slot->EffectProps.Reverb.DecayHFLimit && - Slot->EffectProps.Reverb.AirAbsorptionGainHF < 1.0f) - hfRatio = CalcLimitedHfRatio(hfRatio, - Slot->EffectProps.Reverb.AirAbsorptionGainHF, - Slot->EffectProps.Reverb.DecayTime); - - cw = cosf(F_2PI * hfscale); - // Update the late lines. - UpdateLateLines(Slot->EffectProps.Reverb.Gain, Slot->EffectProps.Reverb.LateReverbGain, - x, Slot->EffectProps.Reverb.Density, Slot->EffectProps.Reverb.DecayTime, - Slot->EffectProps.Reverb.Diffusion, hfRatio, cw, frequency, State); - - if(State->IsEax) - { - // Update the echo line. - UpdateEchoLine(Slot->EffectProps.Reverb.Gain, Slot->EffectProps.Reverb.LateReverbGain, - Slot->EffectProps.Reverb.EchoTime, Slot->EffectProps.Reverb.DecayTime, - Slot->EffectProps.Reverb.Diffusion, Slot->EffectProps.Reverb.EchoDepth, - hfRatio, cw, frequency, State); - - // Update early and late 3D panning. - Update3DPanning(Device, Slot->EffectProps.Reverb.ReflectionsPan, - Slot->EffectProps.Reverb.LateReverbPan, Slot->Gain, State); - } - else - { - /* Update channel gains */ - ALfloat gain = sqrtf(2.0f/Device->NumChan) * ReverbBoost * Slot->Gain; - SetGains(Device, gain, State->Gain); - } -} - - -static ALvoid ALreverbState_Destruct(ALreverbState *State) -{ - free(State->SampleBuffer); - State->SampleBuffer = NULL; -} - -DECLARE_DEFAULT_ALLOCATORS(ALreverbState) - -DEFINE_ALEFFECTSTATE_VTABLE(ALreverbState); - - -typedef struct ALreverbStateFactory { - DERIVE_FROM_TYPE(ALeffectStateFactory); -} ALreverbStateFactory; - -static ALeffectState *ALreverbStateFactory_create(ALreverbStateFactory* UNUSED(factory)) -{ - ALreverbState *state; - ALuint index; - - state = ALreverbState_New(sizeof(*state)); - if(!state) return NULL; - SET_VTABLE2(ALreverbState, ALeffectState, state); - - state->TotalSamples = 0; - state->SampleBuffer = NULL; - - ALfilterState_clear(&state->LpFilter); - ALfilterState_clear(&state->HpFilter); - - state->Mod.Delay.Mask = 0; - state->Mod.Delay.Line = NULL; - state->Mod.Index = 0; - state->Mod.Range = 1; - state->Mod.Depth = 0.0f; - state->Mod.Coeff = 0.0f; - state->Mod.Filter = 0.0f; - - state->Delay.Mask = 0; - state->Delay.Line = NULL; - state->DelayTap[0] = 0; - state->DelayTap[1] = 0; - - state->Early.Gain = 0.0f; - for(index = 0;index < 4;index++) - { - state->Early.Coeff[index] = 0.0f; - state->Early.Delay[index].Mask = 0; - state->Early.Delay[index].Line = NULL; - state->Early.Offset[index] = 0; - } - - state->Decorrelator.Mask = 0; - state->Decorrelator.Line = NULL; - state->DecoTap[0] = 0; - state->DecoTap[1] = 0; - state->DecoTap[2] = 0; - - state->Late.Gain = 0.0f; - state->Late.DensityGain = 0.0f; - state->Late.ApFeedCoeff = 0.0f; - state->Late.MixCoeff = 0.0f; - for(index = 0;index < 4;index++) - { - state->Late.ApCoeff[index] = 0.0f; - state->Late.ApDelay[index].Mask = 0; - state->Late.ApDelay[index].Line = NULL; - state->Late.ApOffset[index] = 0; - - state->Late.Coeff[index] = 0.0f; - state->Late.Delay[index].Mask = 0; - state->Late.Delay[index].Line = NULL; - state->Late.Offset[index] = 0; - - state->Late.LpCoeff[index] = 0.0f; - state->Late.LpSample[index] = 0.0f; - } - - for(index = 0;index < MaxChannels;index++) - { - state->Early.PanGain[index] = 0.0f; - state->Late.PanGain[index] = 0.0f; - } - - state->Echo.DensityGain = 0.0f; - state->Echo.Delay.Mask = 0; - state->Echo.Delay.Line = NULL; - state->Echo.ApDelay.Mask = 0; - state->Echo.ApDelay.Line = NULL; - state->Echo.Coeff = 0.0f; - state->Echo.ApFeedCoeff = 0.0f; - state->Echo.ApCoeff = 0.0f; - state->Echo.Offset = 0; - state->Echo.ApOffset = 0; - state->Echo.LpCoeff = 0.0f; - state->Echo.LpSample = 0.0f; - state->Echo.MixCoeff[0] = 0.0f; - state->Echo.MixCoeff[1] = 0.0f; - - state->Offset = 0; - - state->Gain = state->Late.PanGain; - - return STATIC_CAST(ALeffectState, state); -} - -DEFINE_ALEFFECTSTATEFACTORY_VTABLE(ALreverbStateFactory); - -ALeffectStateFactory *ALreverbStateFactory_getFactory(void) -{ - static ALreverbStateFactory ReverbFactory = { { GET_VTABLE2(ALreverbStateFactory, ALeffectStateFactory) } }; - - return STATIC_CAST(ALeffectStateFactory, &ReverbFactory); -} - - -void ALeaxreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - if(!(val >= AL_EAXREVERB_MIN_DECAY_HFLIMIT && val <= AL_EAXREVERB_MAX_DECAY_HFLIMIT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayHFLimit = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALeaxreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALeaxreverb_setParami(effect, context, param, vals[0]); -} -void ALeaxreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_DENSITY: - if(!(val >= AL_EAXREVERB_MIN_DENSITY && val <= AL_EAXREVERB_MAX_DENSITY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Density = val; - break; - - case AL_EAXREVERB_DIFFUSION: - if(!(val >= AL_EAXREVERB_MIN_DIFFUSION && val <= AL_EAXREVERB_MAX_DIFFUSION)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Diffusion = val; - break; - - case AL_EAXREVERB_GAIN: - if(!(val >= AL_EAXREVERB_MIN_GAIN && val <= AL_EAXREVERB_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Gain = val; - break; - - case AL_EAXREVERB_GAINHF: - if(!(val >= AL_EAXREVERB_MIN_GAINHF && val <= AL_EAXREVERB_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.GainHF = val; - break; - - case AL_EAXREVERB_GAINLF: - if(!(val >= AL_EAXREVERB_MIN_GAINLF && val <= AL_EAXREVERB_MAX_GAINLF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.GainLF = val; - break; - - case AL_EAXREVERB_DECAY_TIME: - if(!(val >= AL_EAXREVERB_MIN_DECAY_TIME && val <= AL_EAXREVERB_MAX_DECAY_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayTime = val; - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - if(!(val >= AL_EAXREVERB_MIN_DECAY_HFRATIO && val <= AL_EAXREVERB_MAX_DECAY_HFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayHFRatio = val; - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - if(!(val >= AL_EAXREVERB_MIN_DECAY_LFRATIO && val <= AL_EAXREVERB_MAX_DECAY_LFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayLFRatio = val; - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_GAIN && val <= AL_EAXREVERB_MAX_REFLECTIONS_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ReflectionsGain = val; - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - if(!(val >= AL_EAXREVERB_MIN_REFLECTIONS_DELAY && val <= AL_EAXREVERB_MAX_REFLECTIONS_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ReflectionsDelay = val; - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_GAIN && val <= AL_EAXREVERB_MAX_LATE_REVERB_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.LateReverbGain = val; - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - if(!(val >= AL_EAXREVERB_MIN_LATE_REVERB_DELAY && val <= AL_EAXREVERB_MAX_LATE_REVERB_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.LateReverbDelay = val; - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - if(!(val >= AL_EAXREVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_EAXREVERB_MAX_AIR_ABSORPTION_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.AirAbsorptionGainHF = val; - break; - - case AL_EAXREVERB_ECHO_TIME: - if(!(val >= AL_EAXREVERB_MIN_ECHO_TIME && val <= AL_EAXREVERB_MAX_ECHO_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.EchoTime = val; - break; - - case AL_EAXREVERB_ECHO_DEPTH: - if(!(val >= AL_EAXREVERB_MIN_ECHO_DEPTH && val <= AL_EAXREVERB_MAX_ECHO_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.EchoDepth = val; - break; - - case AL_EAXREVERB_MODULATION_TIME: - if(!(val >= AL_EAXREVERB_MIN_MODULATION_TIME && val <= AL_EAXREVERB_MAX_MODULATION_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ModulationTime = val; - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - if(!(val >= AL_EAXREVERB_MIN_MODULATION_DEPTH && val <= AL_EAXREVERB_MAX_MODULATION_DEPTH)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ModulationDepth = val; - break; - - case AL_EAXREVERB_HFREFERENCE: - if(!(val >= AL_EAXREVERB_MIN_HFREFERENCE && val <= AL_EAXREVERB_MAX_HFREFERENCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.HFReference = val; - break; - - case AL_EAXREVERB_LFREFERENCE: - if(!(val >= AL_EAXREVERB_MIN_LFREFERENCE && val <= AL_EAXREVERB_MAX_LFREFERENCE)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.LFReference = val; - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - if(!(val >= AL_EAXREVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_EAXREVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.RoomRolloffFactor = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALeaxreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - LockContext(context); - props->Reverb.ReflectionsPan[0] = vals[0]; - props->Reverb.ReflectionsPan[1] = vals[1]; - props->Reverb.ReflectionsPan[2] = vals[2]; - UnlockContext(context); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - if(!(isfinite(vals[0]) && isfinite(vals[1]) && isfinite(vals[2]))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - LockContext(context); - props->Reverb.LateReverbPan[0] = vals[0]; - props->Reverb.LateReverbPan[1] = vals[1]; - props->Reverb.LateReverbPan[2] = vals[2]; - UnlockContext(context); - break; - - default: - ALeaxreverb_setParamf(effect, context, param, vals[0]); - break; - } -} - -void ALeaxreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_DECAY_HFLIMIT: - *val = props->Reverb.DecayHFLimit; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALeaxreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALeaxreverb_getParami(effect, context, param, vals); -} -void ALeaxreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_DENSITY: - *val = props->Reverb.Density; - break; - - case AL_EAXREVERB_DIFFUSION: - *val = props->Reverb.Diffusion; - break; - - case AL_EAXREVERB_GAIN: - *val = props->Reverb.Gain; - break; - - case AL_EAXREVERB_GAINHF: - *val = props->Reverb.GainHF; - break; - - case AL_EAXREVERB_GAINLF: - *val = props->Reverb.GainLF; - break; - - case AL_EAXREVERB_DECAY_TIME: - *val = props->Reverb.DecayTime; - break; - - case AL_EAXREVERB_DECAY_HFRATIO: - *val = props->Reverb.DecayHFRatio; - break; - - case AL_EAXREVERB_DECAY_LFRATIO: - *val = props->Reverb.DecayLFRatio; - break; - - case AL_EAXREVERB_REFLECTIONS_GAIN: - *val = props->Reverb.ReflectionsGain; - break; - - case AL_EAXREVERB_REFLECTIONS_DELAY: - *val = props->Reverb.ReflectionsDelay; - break; - - case AL_EAXREVERB_LATE_REVERB_GAIN: - *val = props->Reverb.LateReverbGain; - break; - - case AL_EAXREVERB_LATE_REVERB_DELAY: - *val = props->Reverb.LateReverbDelay; - break; - - case AL_EAXREVERB_AIR_ABSORPTION_GAINHF: - *val = props->Reverb.AirAbsorptionGainHF; - break; - - case AL_EAXREVERB_ECHO_TIME: - *val = props->Reverb.EchoTime; - break; - - case AL_EAXREVERB_ECHO_DEPTH: - *val = props->Reverb.EchoDepth; - break; - - case AL_EAXREVERB_MODULATION_TIME: - *val = props->Reverb.ModulationTime; - break; - - case AL_EAXREVERB_MODULATION_DEPTH: - *val = props->Reverb.ModulationDepth; - break; - - case AL_EAXREVERB_HFREFERENCE: - *val = props->Reverb.HFReference; - break; - - case AL_EAXREVERB_LFREFERENCE: - *val = props->Reverb.LFReference; - break; - - case AL_EAXREVERB_ROOM_ROLLOFF_FACTOR: - *val = props->Reverb.RoomRolloffFactor; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALeaxreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_EAXREVERB_REFLECTIONS_PAN: - LockContext(context); - vals[0] = props->Reverb.ReflectionsPan[0]; - vals[1] = props->Reverb.ReflectionsPan[1]; - vals[2] = props->Reverb.ReflectionsPan[2]; - UnlockContext(context); - break; - case AL_EAXREVERB_LATE_REVERB_PAN: - LockContext(context); - vals[0] = props->Reverb.LateReverbPan[0]; - vals[1] = props->Reverb.LateReverbPan[1]; - vals[2] = props->Reverb.LateReverbPan[2]; - UnlockContext(context); - break; - - default: - ALeaxreverb_getParamf(effect, context, param, vals); - break; - } -} - -DEFINE_ALEFFECT_VTABLE(ALeaxreverb); - -void ALreverb_setParami(ALeffect *effect, ALCcontext *context, ALenum param, ALint val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - if(!(val >= AL_REVERB_MIN_DECAY_HFLIMIT && val <= AL_REVERB_MAX_DECAY_HFLIMIT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayHFLimit = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALreverb_setParamiv(ALeffect *effect, ALCcontext *context, ALenum param, const ALint *vals) -{ - ALreverb_setParami(effect, context, param, vals[0]); -} -void ALreverb_setParamf(ALeffect *effect, ALCcontext *context, ALenum param, ALfloat val) -{ - ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_REVERB_DENSITY: - if(!(val >= AL_REVERB_MIN_DENSITY && val <= AL_REVERB_MAX_DENSITY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Density = val; - break; - - case AL_REVERB_DIFFUSION: - if(!(val >= AL_REVERB_MIN_DIFFUSION && val <= AL_REVERB_MAX_DIFFUSION)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Diffusion = val; - break; - - case AL_REVERB_GAIN: - if(!(val >= AL_REVERB_MIN_GAIN && val <= AL_REVERB_MAX_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.Gain = val; - break; - - case AL_REVERB_GAINHF: - if(!(val >= AL_REVERB_MIN_GAINHF && val <= AL_REVERB_MAX_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.GainHF = val; - break; - - case AL_REVERB_DECAY_TIME: - if(!(val >= AL_REVERB_MIN_DECAY_TIME && val <= AL_REVERB_MAX_DECAY_TIME)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayTime = val; - break; - - case AL_REVERB_DECAY_HFRATIO: - if(!(val >= AL_REVERB_MIN_DECAY_HFRATIO && val <= AL_REVERB_MAX_DECAY_HFRATIO)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.DecayHFRatio = val; - break; - - case AL_REVERB_REFLECTIONS_GAIN: - if(!(val >= AL_REVERB_MIN_REFLECTIONS_GAIN && val <= AL_REVERB_MAX_REFLECTIONS_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ReflectionsGain = val; - break; - - case AL_REVERB_REFLECTIONS_DELAY: - if(!(val >= AL_REVERB_MIN_REFLECTIONS_DELAY && val <= AL_REVERB_MAX_REFLECTIONS_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.ReflectionsDelay = val; - break; - - case AL_REVERB_LATE_REVERB_GAIN: - if(!(val >= AL_REVERB_MIN_LATE_REVERB_GAIN && val <= AL_REVERB_MAX_LATE_REVERB_GAIN)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.LateReverbGain = val; - break; - - case AL_REVERB_LATE_REVERB_DELAY: - if(!(val >= AL_REVERB_MIN_LATE_REVERB_DELAY && val <= AL_REVERB_MAX_LATE_REVERB_DELAY)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.LateReverbDelay = val; - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - if(!(val >= AL_REVERB_MIN_AIR_ABSORPTION_GAINHF && val <= AL_REVERB_MAX_AIR_ABSORPTION_GAINHF)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.AirAbsorptionGainHF = val; - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - if(!(val >= AL_REVERB_MIN_ROOM_ROLLOFF_FACTOR && val <= AL_REVERB_MAX_ROOM_ROLLOFF_FACTOR)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - props->Reverb.RoomRolloffFactor = val; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALreverb_setParamfv(ALeffect *effect, ALCcontext *context, ALenum param, const ALfloat *vals) -{ - ALreverb_setParamf(effect, context, param, vals[0]); -} - -void ALreverb_getParami(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_REVERB_DECAY_HFLIMIT: - *val = props->Reverb.DecayHFLimit; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALreverb_getParamiv(const ALeffect *effect, ALCcontext *context, ALenum param, ALint *vals) -{ - ALreverb_getParami(effect, context, param, vals); -} -void ALreverb_getParamf(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *val) -{ - const ALeffectProps *props = &effect->Props; - switch(param) - { - case AL_REVERB_DENSITY: - *val = props->Reverb.Density; - break; - - case AL_REVERB_DIFFUSION: - *val = props->Reverb.Diffusion; - break; - - case AL_REVERB_GAIN: - *val = props->Reverb.Gain; - break; - - case AL_REVERB_GAINHF: - *val = props->Reverb.GainHF; - break; - - case AL_REVERB_DECAY_TIME: - *val = props->Reverb.DecayTime; - break; - - case AL_REVERB_DECAY_HFRATIO: - *val = props->Reverb.DecayHFRatio; - break; - - case AL_REVERB_REFLECTIONS_GAIN: - *val = props->Reverb.ReflectionsGain; - break; - - case AL_REVERB_REFLECTIONS_DELAY: - *val = props->Reverb.ReflectionsDelay; - break; - - case AL_REVERB_LATE_REVERB_GAIN: - *val = props->Reverb.LateReverbGain; - break; - - case AL_REVERB_LATE_REVERB_DELAY: - *val = props->Reverb.LateReverbDelay; - break; - - case AL_REVERB_AIR_ABSORPTION_GAINHF: - *val = props->Reverb.AirAbsorptionGainHF; - break; - - case AL_REVERB_ROOM_ROLLOFF_FACTOR: - *val = props->Reverb.RoomRolloffFactor; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} -void ALreverb_getParamfv(const ALeffect *effect, ALCcontext *context, ALenum param, ALfloat *vals) -{ - ALreverb_getParamf(effect, context, param, vals); -} - -DEFINE_ALEFFECT_VTABLE(ALreverb); diff --git a/love/src/jni/openal-soft-1.17.0/Alc/evtqueue.h b/love/src/jni/openal-soft-1.17.0/Alc/evtqueue.h deleted file mode 100644 index 95702d79..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/evtqueue.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef AL_EVTQUEUE_H -#define AL_EVTQUEUE_H - -#include "AL/al.h" - -#include "alMain.h" - -typedef struct MidiEvent { - ALuint64 time; - ALuint event; - union { - ALuint val[2]; - struct { - ALvoid *data; - ALsizei size; - } sysex; - } param; -} MidiEvent; - -typedef struct EvtQueue { - MidiEvent *events; - ALsizei pos; - ALsizei size; - ALsizei maxsize; -} EvtQueue; - -void InitEvtQueue(EvtQueue *queue); -void ResetEvtQueue(EvtQueue *queue); -ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt); - -#endif /* AL_EVTQUEUE_H */ diff --git a/love/src/jni/openal-soft-1.17.0/Alc/helpers.c b/love/src/jni/openal-soft-1.17.0/Alc/helpers.c deleted file mode 100644 index fc879d95..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/helpers.c +++ /dev/null @@ -1,814 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2011 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#ifdef _WIN32 -#ifdef __MINGW32__ -#define _WIN32_IE 0x501 -#else -#define _WIN32_IE 0x400 -#endif -#endif - -#include "config.h" - -#include -#include -#include -#include -#ifdef HAVE_MALLOC_H -#include -#endif - -#ifndef AL_NO_UID_DEFS -#if defined(HAVE_GUIDDEF_H) || defined(HAVE_INITGUID_H) -#define INITGUID -#include -#ifdef HAVE_GUIDDEF_H -#include -#else -#include -#endif - -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80,0x00, 0x00,0xaa,0x00,0x38,0x9b,0x71); -DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80,0x00, 0x00,0xaa,0x00,0x38,0x9b,0x71); - -DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf,0x08, 0x00,0xa0,0xc9,0x25,0xcd,0x16); - -DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e); -DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6); -DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2); -DEFINE_GUID(IID_IAudioRenderClient, 0xf294acfc, 0x3146, 0x4483, 0xa7,0xbf, 0xad,0xdc,0xa7,0xc2,0x60,0xe2); - -#ifdef HAVE_MMDEVAPI -#include -DEFINE_DEVPROPKEY(DEVPKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80,0x20, 0x67,0xd1,0x46,0xa8,0x50,0xe0, 14); -#endif -#endif -#endif /* AL_NO_UID_DEFS */ - -#ifdef HAVE_DLFCN_H -#include -#endif -#ifdef HAVE_INTRIN_H -#include -#endif -#ifdef HAVE_CPUID_H -#include -#endif -#ifdef HAVE_SYS_SYSCONF_H -#include -#endif -#ifdef HAVE_FLOAT_H -#include -#endif -#ifdef HAVE_IEEEFP_H -#include -#endif - -#ifdef _WIN32_IE -#include -#endif - -#include "alMain.h" -#include "alu.h" -#include "atomic.h" -#include "uintmap.h" -#include "vector.h" -#include "alstring.h" -#include "compat.h" -#include "threads.h" - - -extern inline ALuint NextPowerOf2(ALuint value); -extern inline ALint fastf2i(ALfloat f); -extern inline ALuint fastf2u(ALfloat f); - - -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_GCC_GET_CPUID) && (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])) - { - if((cpuinf[0].regs[3]&(1<<25))) - { - caps |= CPU_CAP_SSE; - if((cpuinf[0].regs[3]&(1<<26))) - { - caps |= CPU_CAP_SSE2; - if((cpuinf[0].regs[2]&(1<<19))) - caps |= CPU_CAP_SSE4_1; - } - } - } - } -#elif defined(HAVE_CPUID_INTRINSIC) && (defined(__i386__) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_X64)) - union { - int regs[4]; - char str[sizeof(int[4])]; - } cpuinf[3]; - - (__cpuid)(cpuinf[0].regs, 0); - if(cpuinf[0].regs[0] == 0) - ERR("Failed to get CPUID\n"); - else - { - unsigned int maxfunc = cpuinf[0].regs[0]; - unsigned int maxextfunc; - - (__cpuid)(cpuinf[0].regs, 0x80000000); - 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) - { - (__cpuid)(cpuinf[0].regs, 0x80000002); - (__cpuid)(cpuinf[1].regs, 0x80000003); - (__cpuid)(cpuinf[2].regs, 0x80000004); - TRACE("Name: \"%.16s%.16s%.16s\"\n", cpuinf[0].str, cpuinf[1].str, cpuinf[2].str); - } - - if(maxfunc >= 1) - { - (__cpuid)(cpuinf[0].regs, 1); - if((cpuinf[0].regs[3]&(1<<25))) - { - caps |= CPU_CAP_SSE; - if((cpuinf[0].regs[3]&(1<<26))) - { - caps |= CPU_CAP_SSE2; - if((cpuinf[0].regs[2]&(1<<19))) - caps |= CPU_CAP_SSE4_1; - } - } - } - } -#else - /* Assume support for whatever's supported if we can't check for it */ -#if defined(HAVE_SSE4_1) -#warning "Assuming SSE 4.1 run-time support!" - capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1; -#elif defined(HAVE_SSE2) -#warning "Assuming SSE 2 run-time support!" - capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2; -#elif defined(HAVE_SSE) -#warning "Assuming SSE run-time support!" - capfilter |= CPU_CAP_SSE; -#endif -#endif -#ifdef HAVE_NEON - /* Assume Neon support if compiled with it */ - caps |= CPU_CAP_NEON; -#endif - - TRACE("Extensions:%s%s%s%s%s\n", - ((capfilter&CPU_CAP_SSE) ? ((caps&CPU_CAP_SSE) ? " +SSE" : " -SSE") : ""), - ((capfilter&CPU_CAP_SSE2) ? ((caps&CPU_CAP_SSE2) ? " +SSE2" : " -SSE2") : ""), - ((capfilter&CPU_CAP_SSE4_1) ? ((caps&CPU_CAP_SSE4_1) ? " +SSE4.1" : " -SSE4.1") : ""), - ((capfilter&CPU_CAP_NEON) ? ((caps&CPU_CAP_NEON) ? " +Neon" : " -Neon") : ""), - ((!capfilter) ? " -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 -} - - -void SetMixerFPUMode(FPUCtl *ctl) -{ -#ifdef HAVE_FENV_H - fegetenv(STATIC_CAST(fenv_t, ctl)); -#if defined(__GNUC__) && defined(HAVE_SSE) - if((CPUCapFlags&CPU_CAP_SSE)) - __asm__ __volatile__("stmxcsr %0" : "=m" (*&ctl->sse_state)); -#endif - -#ifdef FE_TOWARDZERO - fesetround(FE_TOWARDZERO); -#endif -#if defined(__GNUC__) && defined(HAVE_SSE) - if((CPUCapFlags&CPU_CAP_SSE)) - { - int sseState = ctl->sse_state; - sseState |= 0x6000; /* set round-to-zero */ - sseState |= 0x8000; /* set flush-to-zero */ - if((CPUCapFlags&CPU_CAP_SSE2)) - sseState |= 0x0040; /* set denormals-are-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, _MCW_RC, &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, _MCW_RC); -#endif -} - -void RestoreFPUMode(const FPUCtl *ctl) -{ -#ifdef HAVE_FENV_H - fesetenv(STATIC_CAST(fenv_t, ctl)); -#if defined(__GNUC__) && defined(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, &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); -#endif -} - - -#ifdef _WIN32 - -static WCHAR *FromUTF8(const char *str) -{ - WCHAR *out = NULL; - int len; - - if((len=MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) > 0) - { - out = calloc(sizeof(WCHAR), len); - MultiByteToWideChar(CP_UTF8, 0, str, -1, out, len); - } - return out; -} - - -void *LoadLib(const char *name) -{ - HANDLE hdl = NULL; - WCHAR *wname; - - wname = FromUTF8(name); - if(!wname) - ERR("Failed to convert UTF-8 filename: \"%s\"\n", name); - else - { - hdl = LoadLibraryW(wname); - free(wname); - } - return hdl; -} -void CloseLib(void *handle) -{ FreeLibrary((HANDLE)handle); } -void *GetSymbol(void *handle, const char *name) -{ - void *ret; - - ret = (void*)GetProcAddress((HANDLE)handle, name); - if(ret == NULL) - ERR("Failed to load %s\n", name); - return ret; -} - -WCHAR *strdupW(const WCHAR *str) -{ - const WCHAR *n; - WCHAR *ret; - size_t len; - - n = str; - while(*n) n++; - len = n - str; - - ret = calloc(sizeof(WCHAR), len+1); - if(ret != NULL) - memcpy(ret, str, sizeof(WCHAR)*len); - return ret; -} - -FILE *al_fopen(const char *fname, const char *mode) -{ - WCHAR *wname=NULL, *wmode=NULL; - FILE *file = NULL; - - wname = FromUTF8(fname); - wmode = FromUTF8(mode); - if(!wname) - ERR("Failed to convert UTF-8 filename: \"%s\"\n", fname); - else if(!wmode) - ERR("Failed to convert UTF-8 mode: \"%s\"\n", mode); - else - file = _wfopen(wname, wmode); - - free(wname); - free(wmode); - - return file; -} - -#else - -#ifdef HAVE_DLFCN_H - -void *LoadLib(const char *name) -{ - const char *err; - void *handle; - - dlerror(); - handle = dlopen(name, RTLD_NOW); - if((err=dlerror()) != NULL) - handle = NULL; - return handle; -} -void CloseLib(void *handle) -{ dlclose(handle); } -void *GetSymbol(void *handle, const char *name) -{ - const char *err; - void *sym; - - dlerror(); - sym = dlsym(handle, name); - if((err=dlerror()) != NULL) - { - WARN("Failed to load %s: %s\n", name, err); - sym = NULL; - } - return sym; -} - -#endif -#endif - - -void al_print(const char *type, const char *func, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fprintf(LogFile, "AL lib: %s %s: ", type, func); - vfprintf(LogFile, fmt, ap); - va_end(ap); - - fflush(LogFile); -} - -#ifdef _WIN32 -static inline int is_slash(int c) -{ return (c == '\\' || c == '/'); } - -FILE *OpenDataFile(const char *fname, const char *subdir) -{ - static const int ids[2] = { CSIDL_APPDATA, CSIDL_COMMON_APPDATA }; - WCHAR *wname=NULL, *wsubdir=NULL; - FILE *f; - int i; - - /* If the path is absolute, open it directly. */ - if(fname[0] != '\0' && fname[1] == ':' && is_slash(fname[2])) - { - if((f=al_fopen(fname, "rb")) != NULL) - { - TRACE("Opened %s\n", fname); - return f; - } - WARN("Could not open %s\n", fname); - return NULL; - } - - /* If it's relative, try the current directory first before the data directories. */ - if((f=al_fopen(fname, "rb")) != NULL) - { - TRACE("Opened %s\n", fname); - return f; - } - WARN("Could not open %s\n", fname); - - wname = FromUTF8(fname); - wsubdir = FromUTF8(subdir); - if(!wname) - ERR("Failed to convert UTF-8 filename: \"%s\"\n", fname); - else if(!wsubdir) - ERR("Failed to convert UTF-8 subdir: \"%s\"\n", subdir); - else for(i = 0;i < 2;i++) - { - WCHAR buffer[PATH_MAX]; - size_t len; - - if(SHGetSpecialFolderPathW(NULL, buffer, ids[i], FALSE) == FALSE) - continue; - - len = lstrlenW(buffer); - if(len > 0 && is_slash(buffer[len-1])) - buffer[--len] = '\0'; - _snwprintf(buffer+len, PATH_MAX-len, L"/%ls/%ls", wsubdir, wname); - len = lstrlenW(buffer); - while(len > 0) - { - --len; - if(buffer[len] == '/') - buffer[len] = '\\'; - } - - if((f=_wfopen(buffer, L"rb")) != NULL) - { - TRACE("Opened %ls\n", buffer); - return f; - } - WARN("Could not open %ls\n", buffer); - } - free(wname); - free(wsubdir); - - return NULL; -} -#else -FILE *OpenDataFile(const char *fname, const char *subdir) -{ - char buffer[PATH_MAX] = ""; - const char *str, *next; - FILE *f; - - if(fname[0] == '/') - { - if((f=al_fopen(fname, "rb")) != NULL) - { - TRACE("Opened %s\n", fname); - return f; - } - WARN("Could not open %s\n", fname); - return NULL; - } - - if((f=al_fopen(fname, "rb")) != NULL) - { - TRACE("Opened %s\n", fname); - return f; - } - WARN("Could not open %s\n", fname); - - if((str=getenv("XDG_DATA_HOME")) != NULL && str[0] != '\0') - snprintf(buffer, sizeof(buffer), "%s/%s/%s", str, subdir, fname); - else if((str=getenv("HOME")) != NULL && str[0] != '\0') - snprintf(buffer, sizeof(buffer), "%s/.local/share/%s/%s", str, subdir, fname); - if(buffer[0]) - { - if((f=al_fopen(buffer, "rb")) != NULL) - { - TRACE("Opened %s\n", buffer); - return f; - } - WARN("Could not open %s\n", buffer); - } - - if((str=getenv("XDG_DATA_DIRS")) == NULL || str[0] == '\0') - str = "/usr/local/share/:/usr/share/"; - - next = str; - while((str=next) != NULL && str[0] != '\0') - { - size_t len; - next = strchr(str, ':'); - - if(!next) - len = strlen(str); - else - { - len = next - str; - next++; - } - - if(len > sizeof(buffer)-1) - len = sizeof(buffer)-1; - strncpy(buffer, str, len); - buffer[len] = '\0'; - snprintf(buffer+len, sizeof(buffer)-len, "/%s/%s", subdir, fname); - - if((f=al_fopen(buffer, "rb")) != NULL) - { - TRACE("Opened %s\n", buffer); - return f; - } - WARN("Could not open %s\n", buffer); - } - - return NULL; -} -#endif - - -void SetRTPriority(void) -{ - ALboolean failed = AL_FALSE; - -#ifdef _WIN32 - if(RTPrioLevel > 0) - failed = !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); -#elif defined(HAVE_PTHREAD_SETSCHEDPARAM) && !defined(__OpenBSD__) - if(RTPrioLevel > 0) - { - struct sched_param param; - /* Use the minimum real-time priority possible for now (on Linux this - * should be 1 for SCHED_RR) */ - param.sched_priority = sched_get_priority_min(SCHED_RR); - failed = !!pthread_setschedparam(pthread_self(), SCHED_RR, ¶m); - } -#else - /* Real-time priority not available */ - failed = (RTPrioLevel>0); -#endif - if(failed) - ERR("Failed to set priority level for thread\n"); -} - - -ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, ALsizei obj_count, ALboolean exact) -{ - vector_ *vecptr = (vector_*)ptr; - if(obj_count < 0) - return AL_FALSE; - if((*vecptr ? (*vecptr)->Capacity : 0) < obj_count) - { - ALsizei old_size = (*vecptr ? (*vecptr)->Size : 0); - void *temp; - - /* Use the next power-of-2 size if we don't need to allocate the exact - * amount. This is preferred when regularly increasing the vector since - * it means fewer reallocations. Though it means it also wastes some - * memory. */ - if(exact == AL_FALSE) - { - obj_count = NextPowerOf2((ALuint)obj_count); - if(obj_count < 0) return AL_FALSE; - } - - /* Need to be explicit with the caller type's base size, because it - * could have extra padding before the start of the array (that is, - * sizeof(*vector_) may not equal base_size). */ - temp = realloc(*vecptr, base_size + obj_size*obj_count); - if(temp == NULL) return AL_FALSE; - - *vecptr = temp; - (*vecptr)->Capacity = obj_count; - (*vecptr)->Size = old_size; - } - return AL_TRUE; -} - -ALboolean vector_resize(char *ptr, size_t base_size, size_t obj_size, ALsizei obj_count) -{ - vector_ *vecptr = (vector_*)ptr; - if(obj_count < 0) - return AL_FALSE; - if(*vecptr || obj_count > 0) - { - if(!vector_reserve((char*)vecptr, base_size, obj_size, obj_count, AL_TRUE)) - return AL_FALSE; - (*vecptr)->Size = obj_count; - } - return AL_TRUE; -} - -ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_pos, const void *datstart, const void *datend) -{ - vector_ *vecptr = (vector_*)ptr; - if(datstart != datend) - { - ptrdiff_t ins_elem = (*vecptr ? ((char*)ins_pos - ((char*)(*vecptr) + base_size)) : - ((char*)ins_pos - (char*)NULL)) / - obj_size; - ptrdiff_t numins = ((const char*)datend - (const char*)datstart) / obj_size; - - assert(numins > 0); - if(INT_MAX-VECTOR_SIZE(*vecptr) <= numins || - !vector_reserve((char*)vecptr, base_size, obj_size, VECTOR_SIZE(*vecptr)+numins, AL_TRUE)) - return AL_FALSE; - - /* NOTE: ins_pos may have been invalidated if *vecptr moved. Use ins_elem instead. */ - if(ins_elem < (*vecptr)->Size) - { - memmove((char*)(*vecptr) + base_size + ((ins_elem+numins)*obj_size), - (char*)(*vecptr) + base_size + ((ins_elem )*obj_size), - ((*vecptr)->Size-ins_elem)*obj_size); - } - memcpy((char*)(*vecptr) + base_size + (ins_elem*obj_size), - datstart, numins*obj_size); - (*vecptr)->Size += (ALsizei)numins; - } - return AL_TRUE; -} - - -extern inline void al_string_deinit(al_string *str); -extern inline ALsizei al_string_length(const_al_string str); -extern inline ALboolean al_string_empty(const_al_string str); -extern inline const al_string_char_type *al_string_get_cstr(const_al_string str); - -void al_string_clear(al_string *str) -{ - /* Reserve one more character than the total size of the string. This is to - * ensure we have space to add a null terminator in the string data so it - * can be used as a C-style string. */ - VECTOR_RESERVE(*str, 1); - VECTOR_RESIZE(*str, 0); - *VECTOR_ITER_END(*str) = 0; -} - -static inline int al_string_compare(const al_string_char_type *str1, ALsizei str1len, - const al_string_char_type *str2, ALsizei str2len) -{ - ALsizei complen = mini(str1len, str2len); - int ret = memcmp(str1, str2, complen); - if(ret == 0) - { - if(str1len > str2len) return 1; - if(str1len < str2len) return -1; - } - return ret; -} -int al_string_cmp(const_al_string str1, const_al_string str2) -{ - return al_string_compare(&VECTOR_FRONT(str1), al_string_length(str1), - &VECTOR_FRONT(str2), al_string_length(str2)); -} -int al_string_cmp_cstr(const_al_string str1, const al_string_char_type *str2) -{ - return al_string_compare(&VECTOR_FRONT(str1), al_string_length(str1), - str2, (ALsizei)strlen(str2)); -} - -void al_string_copy(al_string *str, const_al_string from) -{ - ALsizei len = VECTOR_SIZE(from); - VECTOR_RESERVE(*str, len+1); - VECTOR_RESIZE(*str, 0); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), VECTOR_ITER_BEGIN(from), VECTOR_ITER_BEGIN(from)+len); - *VECTOR_ITER_END(*str) = 0; -} - -void al_string_copy_cstr(al_string *str, const al_string_char_type *from) -{ - size_t len = strlen(from); - VECTOR_RESERVE(*str, len+1); - VECTOR_RESIZE(*str, 0); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, from+len); - *VECTOR_ITER_END(*str) = 0; -} - -void al_string_append_char(al_string *str, const al_string_char_type c) -{ - VECTOR_RESERVE(*str, al_string_length(*str)+2); - VECTOR_PUSH_BACK(*str, c); - *VECTOR_ITER_END(*str) = 0; -} - -void al_string_append_cstr(al_string *str, const al_string_char_type *from) -{ - size_t len = strlen(from); - if(len != 0) - { - VECTOR_RESERVE(*str, al_string_length(*str)+len+1); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, from+len); - *VECTOR_ITER_END(*str) = 0; - } -} - -void al_string_append_range(al_string *str, const al_string_char_type *from, const al_string_char_type *to) -{ - if(to != from) - { - VECTOR_RESERVE(*str, al_string_length(*str)+(to-from)+1); - VECTOR_INSERT(*str, VECTOR_ITER_END(*str), from, to); - *VECTOR_ITER_END(*str) = 0; - } -} - -#ifdef _WIN32 -void al_string_copy_wcstr(al_string *str, const wchar_t *from) -{ - int len; - if((len=WideCharToMultiByte(CP_UTF8, 0, from, -1, NULL, 0, NULL, NULL)) > 0) - { - VECTOR_RESERVE(*str, len); - VECTOR_RESIZE(*str, len-1); - WideCharToMultiByte(CP_UTF8, 0, from, -1, &VECTOR_FRONT(*str), len, NULL, NULL); - *VECTOR_ITER_END(*str) = 0; - } -} -#endif diff --git a/love/src/jni/openal-soft-1.17.0/Alc/hrtf.c b/love/src/jni/openal-soft-1.17.0/Alc/hrtf.c deleted file mode 100644 index 707655a0..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/hrtf.c +++ /dev/null @@ -1,820 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2011 by Chris Robinson - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include - -#include "AL/al.h" -#include "AL/alc.h" -#include "alMain.h" -#include "alSource.h" -#include "alu.h" -#include "hrtf.h" - - -/* Current data set limits defined by the makehrtf utility. */ -#define MIN_IR_SIZE (8) -#define MAX_IR_SIZE (128) -#define MOD_IR_SIZE (8) - -#define MIN_EV_COUNT (5) -#define MAX_EV_COUNT (128) - -#define MIN_AZ_COUNT (1) -#define MAX_AZ_COUNT (128) - -struct Hrtf { - ALuint sampleRate; - ALuint irSize; - ALubyte evCount; - - const ALubyte *azCount; - const ALushort *evOffset; - const ALshort *coeffs; - const ALubyte *delays; - - struct Hrtf *next; -}; - -static const ALchar magicMarker00[8] = "MinPHR00"; -static const ALchar magicMarker01[8] = "MinPHR01"; - -/* First value for pass-through coefficients (remaining are 0), used for omni- - * directional sounds. */ -static const ALfloat PassthruCoeff = 32767.0f * 0.707106781187f/*sqrt(0.5)*/; - -static struct Hrtf *LoadedHrtfs = NULL; - -/* Calculate the elevation indices given the polar elevation in radians. - * This will return two indices between 0 and (evcount - 1) and an - * interpolation factor between 0.0 and 1.0. - */ -static void CalcEvIndices(ALuint evcount, ALfloat ev, ALuint *evidx, ALfloat *evmu) -{ - ev = (F_PI_2 + ev) * (evcount-1) / F_PI; - evidx[0] = fastf2u(ev); - evidx[1] = minu(evidx[0] + 1, evcount-1); - *evmu = ev - evidx[0]; -} - -/* Calculate the azimuth indices given the polar azimuth in radians. This - * will return two indices between 0 and (azcount - 1) and an interpolation - * factor between 0.0 and 1.0. - */ -static void CalcAzIndices(ALuint azcount, ALfloat az, ALuint *azidx, ALfloat *azmu) -{ - az = (F_2PI + az) * azcount / (F_2PI); - azidx[0] = fastf2u(az) % azcount; - azidx[1] = (azidx[0] + 1) % azcount; - *azmu = az - floorf(az); -} - -/* Calculates the normalized HRTF transition factor (delta) from the changes - * in gain and listener to source angle between updates. The result is a - * normalized delta factor that can be used to calculate moving HRIR stepping - * values. - */ -ALfloat CalcHrtfDelta(ALfloat oldGain, ALfloat newGain, const ALfloat olddir[3], const ALfloat newdir[3]) -{ - ALfloat gainChange, angleChange, change; - - // Calculate the normalized dB gain change. - newGain = maxf(newGain, 0.0001f); - oldGain = maxf(oldGain, 0.0001f); - gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f)); - - // Calculate the angle change only when there is enough gain to notice it. - angleChange = 0.0f; - if(gainChange > 0.0001f || newGain > 0.0001f) - { - // No angle change when the directions are equal or degenerate (when - // both have zero length). - if(newdir[0] != olddir[0] || newdir[1] != olddir[1] || newdir[2] != olddir[2]) - { - ALfloat dotp = olddir[0]*newdir[0] + olddir[1]*newdir[1] + olddir[2]*newdir[2]; - angleChange = acosf(clampf(dotp, -1.0f, 1.0f)) / F_PI; - } - } - - // Use the largest of the two changes for the delta factor, and apply a - // significance shaping function to it. - change = maxf(angleChange * 25.0f, gainChange) * 2.0f; - return minf(change, 1.0f); -} - -/* Calculates static HRIR coefficients and delays for the given polar - * elevation and azimuth in radians. Linear interpolation is used to - * increase the apparent resolution of the HRIR data set. The coefficients - * are also normalized and attenuated by the specified gain. - */ -void GetLerpedHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat (*coeffs)[2], ALuint *delays) -{ - ALuint evidx[2], lidx[4], ridx[4]; - ALfloat mu[3], blend[4]; - ALuint i; - - /* Claculate elevation indices and interpolation factor. */ - CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]); - - for(i = 0;i < 2;i++) - { - ALuint azcount = Hrtf->azCount[evidx[i]]; - ALuint evoffset = Hrtf->evOffset[evidx[i]]; - ALuint azidx[2]; - - /* Calculate azimuth indices and interpolation factor for this elevation. */ - CalcAzIndices(azcount, azimuth, azidx, &mu[i]); - - /* Calculate a set of linear HRIR indices for left and right channels. */ - lidx[i*2 + 0] = evoffset + azidx[0]; - lidx[i*2 + 1] = evoffset + azidx[1]; - ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount); - ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount); - } - - /* Calculate 4 blending weights for 2D bilinear interpolation. */ - blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); - blend[1] = ( mu[0]) * (1.0f-mu[2]); - blend[2] = (1.0f-mu[1]) * ( mu[2]); - blend[3] = ( mu[1]) * ( mu[2]); - - /* Calculate the HRIR delays using linear interpolation. */ - delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + - Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + - Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - - /* Calculate the sample offsets for the HRIR indices. */ - lidx[0] *= Hrtf->irSize; - lidx[1] *= Hrtf->irSize; - lidx[2] *= Hrtf->irSize; - lidx[3] *= Hrtf->irSize; - ridx[0] *= Hrtf->irSize; - ridx[1] *= Hrtf->irSize; - ridx[2] *= Hrtf->irSize; - ridx[3] *= Hrtf->irSize; - - /* Calculate the normalized and attenuated HRIR coefficients using linear - * interpolation when there is enough gain to warrant it. Zero the - * coefficients if gain is too low. - */ - if(gain > 0.0001f) - { - ALfloat c; - - gain *= 1.0f/32767.0f; - - i = 0; - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain; - - for(i = 1;i < Hrtf->irSize;i++) - { - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(0.0f, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(0.0f, c, dirfact) * gain; - } - } - else - { - for(i = 0;i < Hrtf->irSize;i++) - { - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - } - } -} - -/* Calculates the moving HRIR target coefficients, target delays, and - * stepping values for the given polar elevation and azimuth in radians. - * Linear interpolation is used to increase the apparent resolution of the - * HRIR data set. The coefficients are also normalized and attenuated by the - * specified gain. Stepping resolution and count is determined using the - * given delta factor between 0.0 and 1.0. - */ -ALuint GetMovingHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat dirfact, ALfloat gain, ALfloat delta, ALint counter, ALfloat (*coeffs)[2], ALuint *delays, ALfloat (*coeffStep)[2], ALint *delayStep) -{ - ALuint evidx[2], lidx[4], ridx[4]; - ALfloat mu[3], blend[4]; - ALfloat left, right; - ALfloat step; - ALuint i; - - /* Claculate elevation indices and interpolation factor. */ - CalcEvIndices(Hrtf->evCount, elevation, evidx, &mu[2]); - - for(i = 0;i < 2;i++) - { - ALuint azcount = Hrtf->azCount[evidx[i]]; - ALuint evoffset = Hrtf->evOffset[evidx[i]]; - ALuint azidx[2]; - - /* Calculate azimuth indices and interpolation factor for this elevation. */ - CalcAzIndices(azcount, azimuth, azidx, &mu[i]); - - /* Calculate a set of linear HRIR indices for left and right channels. */ - lidx[i*2 + 0] = evoffset + azidx[0]; - lidx[i*2 + 1] = evoffset + azidx[1]; - ridx[i*2 + 0] = evoffset + ((azcount-azidx[0]) % azcount); - ridx[i*2 + 1] = evoffset + ((azcount-azidx[1]) % azcount); - } - - // Calculate the stepping parameters. - delta = maxf(floorf(delta*(Hrtf->sampleRate*0.015f) + 0.5f), 1.0f); - step = 1.0f / delta; - - /* Calculate 4 blending weights for 2D bilinear interpolation. */ - blend[0] = (1.0f-mu[0]) * (1.0f-mu[2]); - blend[1] = ( mu[0]) * (1.0f-mu[2]); - blend[2] = (1.0f-mu[1]) * ( mu[2]); - blend[3] = ( mu[1]) * ( mu[2]); - - /* Calculate the HRIR delays using linear interpolation. Then calculate - * the delay stepping values using the target and previous running - * delays. - */ - left = (ALfloat)(delays[0] - (delayStep[0] * counter)); - right = (ALfloat)(delays[1] - (delayStep[1] * counter)); - - delays[0] = fastf2u((Hrtf->delays[lidx[0]]*blend[0] + Hrtf->delays[lidx[1]]*blend[1] + - Hrtf->delays[lidx[2]]*blend[2] + Hrtf->delays[lidx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2u((Hrtf->delays[ridx[0]]*blend[0] + Hrtf->delays[ridx[1]]*blend[1] + - Hrtf->delays[ridx[2]]*blend[2] + Hrtf->delays[ridx[3]]*blend[3]) * - dirfact + 0.5f) << HRTFDELAY_BITS; - - delayStep[0] = fastf2i(step * (delays[0] - left)); - delayStep[1] = fastf2i(step * (delays[1] - right)); - - /* Calculate the sample offsets for the HRIR indices. */ - lidx[0] *= Hrtf->irSize; - lidx[1] *= Hrtf->irSize; - lidx[2] *= Hrtf->irSize; - lidx[3] *= Hrtf->irSize; - ridx[0] *= Hrtf->irSize; - ridx[1] *= Hrtf->irSize; - ridx[2] *= Hrtf->irSize; - ridx[3] *= Hrtf->irSize; - - /* Calculate the normalized and attenuated target HRIR coefficients using - * linear interpolation when there is enough gain to warrant it. Zero - * the target coefficients if gain is too low. Then calculate the - * coefficient stepping values using the target and previous running - * coefficients. - */ - if(gain > 0.0001f) - { - ALfloat c; - - gain *= 1.0f/32767.0f; - - i = 0; - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(PassthruCoeff, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(PassthruCoeff, c, dirfact) * gain; - - coeffStep[i][0] = step * (coeffs[i][0] - left); - coeffStep[i][1] = step * (coeffs[i][1] - right); - - for(i = 1;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - c = (Hrtf->coeffs[lidx[0]+i]*blend[0] + Hrtf->coeffs[lidx[1]+i]*blend[1] + - Hrtf->coeffs[lidx[2]+i]*blend[2] + Hrtf->coeffs[lidx[3]+i]*blend[3]); - coeffs[i][0] = lerp(0.0f, c, dirfact) * gain; - c = (Hrtf->coeffs[ridx[0]+i]*blend[0] + Hrtf->coeffs[ridx[1]+i]*blend[1] + - Hrtf->coeffs[ridx[2]+i]*blend[2] + Hrtf->coeffs[ridx[3]+i]*blend[3]); - coeffs[i][1] = lerp(0.0f, c, dirfact) * gain; - - coeffStep[i][0] = step * (coeffs[i][0] - left); - coeffStep[i][1] = step * (coeffs[i][1] - right); - } - } - else - { - for(i = 0;i < Hrtf->irSize;i++) - { - left = coeffs[i][0] - (coeffStep[i][0] * counter); - right = coeffs[i][1] - (coeffStep[i][1] * counter); - - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - - coeffStep[i][0] = step * -left; - coeffStep[i][1] = step * -right; - } - } - - /* The stepping count is the number of samples necessary for the HRIR to - * complete its transition. The mixer will only apply stepping for this - * many samples. - */ - return fastf2u(delta); -} - - -static struct Hrtf *LoadHrtf00(FILE *f, ALuint deviceRate) -{ - const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; - struct Hrtf *Hrtf = NULL; - ALboolean failed = AL_FALSE; - ALuint rate = 0, irCount = 0; - ALushort irSize = 0; - ALubyte evCount = 0; - ALubyte *azCount = NULL; - ALushort *evOffset = NULL; - ALshort *coeffs = NULL; - ALubyte *delays = NULL; - ALuint i, j; - - rate = fgetc(f); - rate |= fgetc(f)<<8; - rate |= fgetc(f)<<16; - rate |= fgetc(f)<<24; - - irCount = fgetc(f); - irCount |= fgetc(f)<<8; - - irSize = fgetc(f); - irSize |= fgetc(f)<<8; - - evCount = fgetc(f); - - if(rate != deviceRate) - { - ERR("HRIR rate does not match device rate: rate=%d (%d)\n", - rate, deviceRate); - failed = AL_TRUE; - } - if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE)) - { - ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n", - irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE); - failed = AL_TRUE; - } - if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT) - { - ERR("Unsupported elevation count: evCount=%d (%d to %d)\n", - evCount, MIN_EV_COUNT, MAX_EV_COUNT); - failed = AL_TRUE; - } - - if(failed) - return NULL; - - azCount = malloc(sizeof(azCount[0])*evCount); - evOffset = malloc(sizeof(evOffset[0])*evCount); - if(azCount == NULL || evOffset == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - - if(!failed) - { - evOffset[0] = fgetc(f); - evOffset[0] |= fgetc(f)<<8; - for(i = 1;i < evCount;i++) - { - evOffset[i] = fgetc(f); - evOffset[i] |= fgetc(f)<<8; - if(evOffset[i] <= evOffset[i-1]) - { - ERR("Invalid evOffset: evOffset[%d]=%d (last=%d)\n", - i, evOffset[i], evOffset[i-1]); - failed = AL_TRUE; - } - - azCount[i-1] = evOffset[i] - evOffset[i-1]; - if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT) - { - ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", - i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT); - failed = AL_TRUE; - } - } - if(irCount <= evOffset[i-1]) - { - ERR("Invalid evOffset: evOffset[%d]=%d (irCount=%d)\n", - i-1, evOffset[i-1], irCount); - failed = AL_TRUE; - } - - azCount[i-1] = irCount - evOffset[i-1]; - if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT) - { - ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", - i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT); - failed = AL_TRUE; - } - } - - if(!failed) - { - coeffs = malloc(sizeof(coeffs[0])*irSize*irCount); - delays = malloc(sizeof(delays[0])*irCount); - if(coeffs == NULL || delays == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - for(i = 0;i < irCount*irSize;i+=irSize) - { - for(j = 0;j < irSize;j++) - { - ALshort coeff; - coeff = fgetc(f); - coeff |= fgetc(f)<<8; - coeffs[i+j] = coeff; - } - } - for(i = 0;i < irCount;i++) - { - delays[i] = fgetc(f); - if(delays[i] > maxDelay) - { - ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay); - failed = AL_TRUE; - } - } - - if(feof(f)) - { - ERR("Premature end of data\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - Hrtf = malloc(sizeof(struct Hrtf)); - if(Hrtf == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - Hrtf->sampleRate = rate; - Hrtf->irSize = irSize; - Hrtf->evCount = evCount; - Hrtf->azCount = azCount; - Hrtf->evOffset = evOffset; - Hrtf->coeffs = coeffs; - Hrtf->delays = delays; - Hrtf->next = NULL; - return Hrtf; - } - - free(azCount); - free(evOffset); - free(coeffs); - free(delays); - return NULL; -} - - -static struct Hrtf *LoadHrtf01(FILE *f, ALuint deviceRate) -{ - const ALubyte maxDelay = SRC_HISTORY_LENGTH-1; - struct Hrtf *Hrtf = NULL; - ALboolean failed = AL_FALSE; - ALuint rate = 0, irCount = 0; - ALubyte irSize = 0, evCount = 0; - ALubyte *azCount = NULL; - ALushort *evOffset = NULL; - ALshort *coeffs = NULL; - ALubyte *delays = NULL; - ALuint i, j; - - rate = fgetc(f); - rate |= fgetc(f)<<8; - rate |= fgetc(f)<<16; - rate |= fgetc(f)<<24; - - irSize = fgetc(f); - - evCount = fgetc(f); - - if(rate != deviceRate) - { - ERR("HRIR rate does not match device rate: rate=%d (%d)\n", - rate, deviceRate); - failed = AL_TRUE; - } - if(irSize < MIN_IR_SIZE || irSize > MAX_IR_SIZE || (irSize%MOD_IR_SIZE)) - { - ERR("Unsupported HRIR size: irSize=%d (%d to %d by %d)\n", - irSize, MIN_IR_SIZE, MAX_IR_SIZE, MOD_IR_SIZE); - failed = AL_TRUE; - } - if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT) - { - ERR("Unsupported elevation count: evCount=%d (%d to %d)\n", - evCount, MIN_EV_COUNT, MAX_EV_COUNT); - failed = AL_TRUE; - } - - if(failed) - return NULL; - - azCount = malloc(sizeof(azCount[0])*evCount); - evOffset = malloc(sizeof(evOffset[0])*evCount); - if(azCount == NULL || evOffset == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - - if(!failed) - { - for(i = 0;i < evCount;i++) - { - azCount[i] = fgetc(f); - if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT) - { - ERR("Unsupported azimuth count: azCount[%d]=%d (%d to %d)\n", - i, azCount[i], MIN_AZ_COUNT, MAX_AZ_COUNT); - failed = AL_TRUE; - } - } - } - - if(!failed) - { - evOffset[0] = 0; - irCount = azCount[0]; - for(i = 1;i < evCount;i++) - { - evOffset[i] = evOffset[i-1] + azCount[i-1]; - irCount += azCount[i]; - } - - coeffs = malloc(sizeof(coeffs[0])*irSize*irCount); - delays = malloc(sizeof(delays[0])*irCount); - if(coeffs == NULL || delays == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - for(i = 0;i < irCount*irSize;i+=irSize) - { - for(j = 0;j < irSize;j++) - { - ALshort coeff; - coeff = fgetc(f); - coeff |= fgetc(f)<<8; - coeffs[i+j] = coeff; - } - } - for(i = 0;i < irCount;i++) - { - delays[i] = fgetc(f); - if(delays[i] > maxDelay) - { - ERR("Invalid delays[%d]: %d (%d)\n", i, delays[i], maxDelay); - failed = AL_TRUE; - } - } - - if(feof(f)) - { - ERR("Premature end of data\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - Hrtf = malloc(sizeof(struct Hrtf)); - if(Hrtf == NULL) - { - ERR("Out of memory.\n"); - failed = AL_TRUE; - } - } - - if(!failed) - { - Hrtf->sampleRate = rate; - Hrtf->irSize = irSize; - Hrtf->evCount = evCount; - Hrtf->azCount = azCount; - Hrtf->evOffset = evOffset; - Hrtf->coeffs = coeffs; - Hrtf->delays = delays; - Hrtf->next = NULL; - return Hrtf; - } - - free(azCount); - free(evOffset); - free(coeffs); - free(delays); - return NULL; -} - - -static struct Hrtf *LoadHrtf(ALuint deviceRate) -{ - const char *fnamelist = "default-%r.mhr"; - - ConfigValueStr(NULL, "hrtf_tables", &fnamelist); - while(*fnamelist != '\0') - { - struct Hrtf *Hrtf = NULL; - char fname[PATH_MAX]; - const char *next; - ALchar magic[8]; - ALuint i; - FILE *f; - - i = 0; - while(isspace(*fnamelist) || *fnamelist == ',') - fnamelist++; - next = fnamelist; - while(*(fnamelist=next) != '\0' && *fnamelist != ',') - { - next = strpbrk(fnamelist, "%,"); - while(fnamelist != next && *fnamelist && i < sizeof(fname)) - fname[i++] = *(fnamelist++); - - if(!next || *next == ',') - break; - - /* *next == '%' */ - next++; - if(*next == 'r') - { - int wrote = snprintf(&fname[i], sizeof(fname)-i, "%u", deviceRate); - i += minu(wrote, sizeof(fname)-i); - next++; - } - else if(*next == '%') - { - if(i < sizeof(fname)) - fname[i++] = '%'; - next++; - } - else - ERR("Invalid marker '%%%c'\n", *next); - } - i = minu(i, sizeof(fname)-1); - fname[i] = '\0'; - while(i > 0 && isspace(fname[i-1])) - i--; - fname[i] = '\0'; - - if(fname[0] == '\0') - continue; - - TRACE("Loading %s...\n", fname); - f = OpenDataFile(fname, "openal/hrtf"); - if(f == NULL) - { - ERR("Could not open %s\n", fname); - continue; - } - - if(fread(magic, 1, sizeof(magic), f) != sizeof(magic)) - ERR("Failed to read header from %s\n", fname); - else - { - if(memcmp(magic, magicMarker00, sizeof(magicMarker00)) == 0) - { - TRACE("Detected data set format v0\n"); - Hrtf = LoadHrtf00(f, deviceRate); - } - else if(memcmp(magic, magicMarker01, sizeof(magicMarker01)) == 0) - { - TRACE("Detected data set format v1\n"); - Hrtf = LoadHrtf01(f, deviceRate); - } - else - ERR("Invalid header in %s: \"%.8s\"\n", fname, magic); - } - - fclose(f); - f = NULL; - - if(Hrtf) - { - Hrtf->next = LoadedHrtfs; - LoadedHrtfs = Hrtf; - TRACE("Loaded HRTF support for format: %s %uhz\n", - DevFmtChannelsString(DevFmtStereo), Hrtf->sampleRate); - return Hrtf; - } - - ERR("Failed to load %s\n", fname); - } - - return NULL; -} - -const struct Hrtf *GetHrtf(enum DevFmtChannels chans, ALCuint srate) -{ - if(chans == DevFmtStereo) - { - struct Hrtf *Hrtf = LoadedHrtfs; - while(Hrtf != NULL) - { - if(srate == Hrtf->sampleRate) - return Hrtf; - Hrtf = Hrtf->next; - } - - Hrtf = LoadHrtf(srate); - if(Hrtf != NULL) - return Hrtf; - } - ERR("Incompatible format: %s %uhz\n", DevFmtChannelsString(chans), srate); - return NULL; -} - -ALCboolean FindHrtfFormat(enum DevFmtChannels *chans, ALCuint *srate) -{ - const struct Hrtf *hrtf = LoadedHrtfs; - while(hrtf != NULL) - { - if(*srate == hrtf->sampleRate) - break; - hrtf = hrtf->next; - } - - if(hrtf == NULL) - { - hrtf = LoadHrtf(*srate); - if(hrtf == NULL) return ALC_FALSE; - } - - *chans = DevFmtStereo; - *srate = hrtf->sampleRate; - return ALC_TRUE; -} - -void FreeHrtfs(void) -{ - struct Hrtf *Hrtf = NULL; - - while((Hrtf=LoadedHrtfs) != NULL) - { - LoadedHrtfs = Hrtf->next; - free((void*)Hrtf->azCount); - free((void*)Hrtf->evOffset); - free((void*)Hrtf->coeffs); - free((void*)Hrtf->delays); - free(Hrtf); - } -} - -ALuint GetHrtfIrSize (const struct Hrtf *Hrtf) -{ - return Hrtf->irSize; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/hrtf.h b/love/src/jni/openal-soft-1.17.0/Alc/hrtf.h deleted file mode 100644 index 938bf552..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/hrtf.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ALC_HRTF_H -#define ALC_HRTF_H - -#include "AL/al.h" -#include "AL/alc.h" - -enum DevFmtChannels; - -struct Hrtf; - -#define HRIR_BITS (7) -#define HRIR_LENGTH (1< -#include -#include - -#include "midi/base.h" - -#include "alMidi.h" -#include "alMain.h" -#include "alError.h" -#include "alThunk.h" -#include "evtqueue.h" -#include "rwlock.h" -#include "alu.h" - - -extern inline ALboolean IsValidCtrlInput(int cc); - -extern inline size_t Reader_read(Reader *self, void *buf, size_t len); - - -/* MIDI events */ -#define SYSEX_EVENT (0xF0) - - -void InitEvtQueue(EvtQueue *queue) -{ - queue->events = NULL; - queue->maxsize = 0; - queue->size = 0; - queue->pos = 0; -} - -void ResetEvtQueue(EvtQueue *queue) -{ - ALsizei i; - for(i = 0;i < queue->size;i++) - { - if(queue->events[i].event == SYSEX_EVENT) - { - free(queue->events[i].param.sysex.data); - queue->events[i].param.sysex.data = NULL; - } - } - - free(queue->events); - queue->events = NULL; - queue->maxsize = 0; - queue->size = 0; - queue->pos = 0; -} - -ALenum InsertEvtQueue(EvtQueue *queue, const MidiEvent *evt) -{ - ALsizei pos; - - if(queue->maxsize == queue->size) - { - if(queue->pos > 0) - { - /* Queue has some stale entries, remove them to make space for more - * events. */ - for(pos = 0;pos < queue->pos;pos++) - { - if(queue->events[pos].event == SYSEX_EVENT) - { - free(queue->events[pos].param.sysex.data); - queue->events[pos].param.sysex.data = NULL; - } - } - memmove(&queue->events[0], &queue->events[queue->pos], - (queue->size-queue->pos)*sizeof(queue->events[0])); - queue->size -= queue->pos; - queue->pos = 0; - } - else - { - /* Queue is full, double the allocated space. */ - void *temp = NULL; - ALsizei newsize; - - newsize = (queue->maxsize ? (queue->maxsize<<1) : 16); - if(newsize > queue->maxsize) - temp = realloc(queue->events, newsize * sizeof(queue->events[0])); - if(!temp) - return AL_OUT_OF_MEMORY; - - queue->events = temp; - queue->maxsize = newsize; - } - } - - pos = queue->pos; - if(queue->size > 0) - { - ALsizei high = queue->size - 1; - while(pos < high) - { - ALsizei mid = pos + (high-pos)/2; - if(queue->events[mid].time < evt->time) - pos = mid + 1; - else - high = mid; - } - while(pos < queue->size && queue->events[pos].time <= evt->time) - pos++; - - if(pos < queue->size) - memmove(&queue->events[pos+1], &queue->events[pos], - (queue->size-pos)*sizeof(queue->events[0])); - } - - queue->events[pos] = *evt; - queue->size++; - - return AL_NO_ERROR; -} - - -void MidiSynth_Construct(MidiSynth *self, ALCdevice *device) -{ - InitEvtQueue(&self->EventQueue); - - RWLockInit(&self->Lock); - - self->Soundfonts = NULL; - self->NumSoundfonts = 0; - - self->Gain = 1.0f; - self->State = AL_INITIAL; - - self->ClockBase = 0; - self->SamplesDone = 0; - self->SampleRate = device->Frequency; -} - -void MidiSynth_Destruct(MidiSynth *self) -{ - ALsizei i; - - for(i = 0;i < self->NumSoundfonts;i++) - DecrementRef(&self->Soundfonts[i]->ref); - free(self->Soundfonts); - self->Soundfonts = NULL; - self->NumSoundfonts = 0; - - ResetEvtQueue(&self->EventQueue); -} - - -ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) -{ - ALCdevice *device = context->Device; - ALsoundfont **sfonts; - ALsizei i; - - if(self->State != AL_INITIAL && self->State != AL_STOPPED) - return AL_INVALID_OPERATION; - - sfonts = calloc(1, count * sizeof(sfonts[0])); - if(!sfonts) return AL_OUT_OF_MEMORY; - - for(i = 0;i < count;i++) - { - if(ids[i] == 0) - sfonts[i] = ALsoundfont_getDefSoundfont(context); - else if(!(sfonts[i]=LookupSfont(device, ids[i]))) - { - free(sfonts); - return AL_INVALID_VALUE; - } - } - - for(i = 0;i < count;i++) - IncrementRef(&sfonts[i]->ref); - sfonts = ExchangePtr((XchgPtr*)&self->Soundfonts, sfonts); - count = ExchangeInt(&self->NumSoundfonts, count); - - for(i = 0;i < count;i++) - DecrementRef(&sfonts[i]->ref); - free(sfonts); - - return AL_NO_ERROR; -} - -extern inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain); -extern inline ALfloat MidiSynth_getGain(const MidiSynth *self); -extern inline void MidiSynth_setState(MidiSynth *self, ALenum state); -extern inline ALenum MidiSynth_getState(const MidiSynth *self); - -void MidiSynth_stop(MidiSynth *self) -{ - ResetEvtQueue(&self->EventQueue); - - self->ClockBase = 0; - self->SamplesDone = 0; -} - -extern inline void MidiSynth_reset(MidiSynth *self); -extern inline ALuint64 MidiSynth_getTime(const MidiSynth *self); -extern inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self); - -void MidiSynth_setSampleRate(MidiSynth *self, ALuint srate) -{ - if(self->SampleRate != srate) - { - self->ClockBase += self->SamplesDone * MIDI_CLOCK_RES / self->SampleRate; - self->SamplesDone = 0; - self->SampleRate = srate; - } -} - -extern inline void MidiSynth_update(MidiSynth *self, ALCdevice *device); - -ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2) -{ - MidiEvent entry; - entry.time = time; - entry.event = event; - entry.param.val[0] = param1; - entry.param.val[1] = param2; - return InsertEvtQueue(&self->EventQueue, &entry); -} - -ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size) -{ - MidiEvent entry; - ALenum err; - - entry.time = time; - entry.event = SYSEX_EVENT; - entry.param.sysex.size = size; - entry.param.sysex.data = malloc(size); - if(!entry.param.sysex.data) - return AL_OUT_OF_MEMORY; - memcpy(entry.param.sysex.data, data, size); - - err = InsertEvtQueue(&self->EventQueue, &entry); - if(err != AL_NO_ERROR) - free(entry.param.sysex.data); - return err; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/midi/base.h b/love/src/jni/openal-soft-1.17.0/Alc/midi/base.h deleted file mode 100644 index 157f2399..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/midi/base.h +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef AL_MIDI_BASE_H -#define AL_MIDI_BASE_H - -#include "alMain.h" -#include "atomic.h" -#include "evtqueue.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct ALsoundfont; - -typedef size_t (*ReaderCb)(void *ptr, size_t size, void *stream); -typedef struct Reader { - ReaderCb cb; - void *ptr; - int error; -} Reader; -inline size_t Reader_read(Reader *self, void *buf, size_t len) -{ - size_t got = (!self->error) ? self->cb(buf, len, self->ptr) : 0; - if(got < len) self->error = 1; - return got; -} -#define READERR(x_) ((x_)->error) - -ALboolean loadSf2(Reader *stream, struct ALsoundfont *sfont, ALCcontext *context); - - -#define MIDI_CLOCK_RES U64(1000000000) - - -struct MidiSynthVtable; - -typedef struct MidiSynth { - EvtQueue EventQueue; - - ALuint64 ClockBase; - ALuint SamplesDone; - ALuint SampleRate; - - /* NOTE: This rwlock is for the state and soundfont. The EventQueue and - * related must instead use the device lock as they're used in the mixer - * thread. - */ - RWLock Lock; - - struct ALsoundfont **Soundfonts; - ALsizei NumSoundfonts; - - volatile ALfloat Gain; - volatile ALenum State; - - const struct MidiSynthVtable *vtbl; -} MidiSynth; - -void MidiSynth_Construct(MidiSynth *self, ALCdevice *device); -void MidiSynth_Destruct(MidiSynth *self); -ALenum MidiSynth_selectSoundfonts(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); -inline void MidiSynth_setGain(MidiSynth *self, ALfloat gain) { self->Gain = gain; } -inline ALfloat MidiSynth_getGain(const MidiSynth *self) { return self->Gain; } -inline void MidiSynth_setState(MidiSynth *self, ALenum state) { ExchangeInt(&self->State, state); } -inline ALenum MidiSynth_getState(const MidiSynth *self) { return self->State; } -void MidiSynth_stop(MidiSynth *self); -inline void MidiSynth_reset(MidiSynth *self) { MidiSynth_stop(self); } -inline ALuint64 MidiSynth_getTime(const MidiSynth *self) -{ return self->ClockBase + (self->SamplesDone*MIDI_CLOCK_RES/self->SampleRate); } -inline ALuint64 MidiSynth_getNextEvtTime(const MidiSynth *self) -{ - if(self->EventQueue.pos == self->EventQueue.size) - return UINT64_MAX; - return self->EventQueue.events[self->EventQueue.pos].time; -} -void MidiSynth_setSampleRate(MidiSynth *self, ALuint srate); -inline void MidiSynth_update(MidiSynth *self, ALCdevice *device) -{ MidiSynth_setSampleRate(self, device->Frequency); } -ALenum MidiSynth_insertEvent(MidiSynth *self, ALuint64 time, ALuint event, ALsizei param1, ALsizei param2); -ALenum MidiSynth_insertSysExEvent(MidiSynth *self, ALuint64 time, const ALbyte *data, ALsizei size); - - -struct MidiSynthVtable { - void (*const Destruct)(MidiSynth *self); - - ALenum (*const selectSoundfonts)(MidiSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); - - void (*const setGain)(MidiSynth *self, ALfloat gain); - - void (*const stop)(MidiSynth *self); - void (*const reset)(MidiSynth *self); - - void (*const update)(MidiSynth *self, ALCdevice *device); - void (*const process)(MidiSynth *self, ALuint samples, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); - - void (*const Delete)(void *ptr); -}; - -#define DEFINE_MIDISYNTH_VTABLE(T) \ -DECLARE_THUNK(T, MidiSynth, void, Destruct) \ -DECLARE_THUNK3(T, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) \ -DECLARE_THUNK1(T, MidiSynth, void, setGain, ALfloat) \ -DECLARE_THUNK(T, MidiSynth, void, stop) \ -DECLARE_THUNK(T, MidiSynth, void, reset) \ -DECLARE_THUNK1(T, MidiSynth, void, update, ALCdevice*) \ -DECLARE_THUNK2(T, MidiSynth, void, process, ALuint, ALfloatBUFFERSIZE*restrict) \ -static void T##_MidiSynth_Delete(void *ptr) \ -{ T##_Delete(STATIC_UPCAST(T, MidiSynth, (MidiSynth*)ptr)); } \ - \ -static const struct MidiSynthVtable T##_MidiSynth_vtable = { \ - T##_MidiSynth_Destruct, \ - \ - T##_MidiSynth_selectSoundfonts, \ - T##_MidiSynth_setGain, \ - T##_MidiSynth_stop, \ - T##_MidiSynth_reset, \ - T##_MidiSynth_update, \ - T##_MidiSynth_process, \ - \ - T##_MidiSynth_Delete, \ -} - - -MidiSynth *SSynth_create(ALCdevice *device); -MidiSynth *FSynth_create(ALCdevice *device); -MidiSynth *DSynth_create(ALCdevice *device); - -MidiSynth *SynthCreate(ALCdevice *device); - -#ifdef __cplusplus -} -#endif - -#endif /* AL_MIDI_BASE_H */ diff --git a/love/src/jni/openal-soft-1.17.0/Alc/midi/dummy.c b/love/src/jni/openal-soft-1.17.0/Alc/midi/dummy.c deleted file mode 100644 index d50b8fef..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/midi/dummy.c +++ /dev/null @@ -1,76 +0,0 @@ - -#include "config.h" - -#include -#include -#include -#include - -#include "alMain.h" -#include "alError.h" -#include "evtqueue.h" -#include "rwlock.h" -#include "alu.h" - -#include "midi/base.h" - -typedef struct DSynth { - DERIVE_FROM_TYPE(MidiSynth); -} DSynth; - -static void DSynth_Construct(DSynth *self, ALCdevice *device); -static DECLARE_FORWARD(DSynth, MidiSynth, void, Destruct) -static DECLARE_FORWARD3(DSynth, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) -static DECLARE_FORWARD1(DSynth, MidiSynth, void, setGain, ALfloat) -static DECLARE_FORWARD(DSynth, MidiSynth, void, stop) -static DECLARE_FORWARD(DSynth, MidiSynth, void, reset) -static DECLARE_FORWARD1(DSynth, MidiSynth, void, update, ALCdevice*) -static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); -DECLARE_DEFAULT_ALLOCATORS(DSynth) -DEFINE_MIDISYNTH_VTABLE(DSynth); - - -static void DSynth_Construct(DSynth *self, ALCdevice *device) -{ - MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device); - SET_VTABLE2(DSynth, MidiSynth, self); -} - - -static void DSynth_processQueue(DSynth *self, ALuint64 time) -{ - EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; - - while(queue->pos < queue->size && queue->events[queue->pos].time <= time) - queue->pos++; -} - -static void DSynth_process(DSynth *self, ALuint SamplesToDo, ALfloatBUFFERSIZE*restrict UNUSED(DryBuffer)) -{ - MidiSynth *synth = STATIC_CAST(MidiSynth, self); - ALuint64 curtime; - - if(synth->State != AL_PLAYING) - return; - - synth->SamplesDone += SamplesToDo; - synth->ClockBase += (synth->SamplesDone/synth->SampleRate) * MIDI_CLOCK_RES; - synth->SamplesDone %= synth->SampleRate; - - curtime = MidiSynth_getTime(synth); - DSynth_processQueue(self, maxi64(curtime-1, 0)); -} - - -MidiSynth *DSynth_create(ALCdevice *device) -{ - DSynth *synth = DSynth_New(sizeof(*synth)); - if(!synth) - { - ERR("Failed to allocate DSynth\n"); - return NULL; - } - memset(synth, 0, sizeof(*synth)); - DSynth_Construct(synth, device); - return STATIC_CAST(MidiSynth, synth); -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/midi/fluidsynth.c b/love/src/jni/openal-soft-1.17.0/Alc/midi/fluidsynth.c deleted file mode 100644 index 82159127..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/midi/fluidsynth.c +++ /dev/null @@ -1,930 +0,0 @@ - -#include "config.h" - -#include -#include -#include - -#include "midi/base.h" - -#include "alMain.h" -#include "alError.h" -#include "alMidi.h" -#include "alu.h" -#include "compat.h" -#include "evtqueue.h" -#include "rwlock.h" - -#ifdef HAVE_FLUIDSYNTH - -#include - - -#ifdef HAVE_DYNLOAD -#define FLUID_FUNCS(MAGIC) \ - MAGIC(new_fluid_synth); \ - MAGIC(delete_fluid_synth); \ - MAGIC(new_fluid_settings); \ - MAGIC(delete_fluid_settings); \ - MAGIC(fluid_settings_setint); \ - MAGIC(fluid_settings_setnum); \ - MAGIC(fluid_synth_noteon); \ - MAGIC(fluid_synth_noteoff); \ - MAGIC(fluid_synth_program_change); \ - MAGIC(fluid_synth_pitch_bend); \ - MAGIC(fluid_synth_channel_pressure); \ - MAGIC(fluid_synth_cc); \ - MAGIC(fluid_synth_sysex); \ - MAGIC(fluid_synth_bank_select); \ - MAGIC(fluid_synth_set_channel_type); \ - MAGIC(fluid_synth_all_sounds_off); \ - MAGIC(fluid_synth_system_reset); \ - MAGIC(fluid_synth_set_gain); \ - MAGIC(fluid_synth_set_sample_rate); \ - MAGIC(fluid_synth_write_float); \ - MAGIC(fluid_synth_add_sfloader); \ - MAGIC(fluid_synth_sfload); \ - MAGIC(fluid_synth_sfunload); \ - MAGIC(fluid_synth_alloc_voice); \ - MAGIC(fluid_synth_start_voice); \ - MAGIC(fluid_voice_gen_set); \ - MAGIC(fluid_voice_add_mod); \ - MAGIC(fluid_mod_set_source1); \ - MAGIC(fluid_mod_set_source2); \ - MAGIC(fluid_mod_set_amount); \ - MAGIC(fluid_mod_set_dest); - -void *fsynth_handle = NULL; -#define DECL_FUNC(x) __typeof(x) *p##x -FLUID_FUNCS(DECL_FUNC) -#undef DECL_FUNC - -#define new_fluid_synth pnew_fluid_synth -#define delete_fluid_synth pdelete_fluid_synth -#define new_fluid_settings pnew_fluid_settings -#define delete_fluid_settings pdelete_fluid_settings -#define fluid_settings_setint pfluid_settings_setint -#define fluid_settings_setnum pfluid_settings_setnum -#define fluid_synth_noteon pfluid_synth_noteon -#define fluid_synth_noteoff pfluid_synth_noteoff -#define fluid_synth_program_change pfluid_synth_program_change -#define fluid_synth_pitch_bend pfluid_synth_pitch_bend -#define fluid_synth_channel_pressure pfluid_synth_channel_pressure -#define fluid_synth_cc pfluid_synth_cc -#define fluid_synth_sysex pfluid_synth_sysex -#define fluid_synth_bank_select pfluid_synth_bank_select -#define fluid_synth_set_channel_type pfluid_synth_set_channel_type -#define fluid_synth_all_sounds_off pfluid_synth_all_sounds_off -#define fluid_synth_system_reset pfluid_synth_system_reset -#define fluid_synth_set_gain pfluid_synth_set_gain -#define fluid_synth_set_sample_rate pfluid_synth_set_sample_rate -#define fluid_synth_write_float pfluid_synth_write_float -#define fluid_synth_add_sfloader pfluid_synth_add_sfloader -#define fluid_synth_sfload pfluid_synth_sfload -#define fluid_synth_sfunload pfluid_synth_sfunload -#define fluid_synth_alloc_voice pfluid_synth_alloc_voice -#define fluid_synth_start_voice pfluid_synth_start_voice -#define fluid_voice_gen_set pfluid_voice_gen_set -#define fluid_voice_add_mod pfluid_voice_add_mod -#define fluid_mod_set_source1 pfluid_mod_set_source1 -#define fluid_mod_set_source2 pfluid_mod_set_source2 -#define fluid_mod_set_amount pfluid_mod_set_amount -#define fluid_mod_set_dest pfluid_mod_set_dest - -static ALboolean LoadFSynth(void) -{ - ALboolean ret = AL_TRUE; - if(!fsynth_handle) - { - fsynth_handle = LoadLib("libfluidsynth.so.1"); - if(!fsynth_handle) return AL_FALSE; - -#define LOAD_FUNC(x) do { \ - p##x = GetSymbol(fsynth_handle, #x); \ - if(!p##x) ret = AL_FALSE; \ -} while(0) - FLUID_FUNCS(LOAD_FUNC) -#undef LOAD_FUNC - - if(ret == AL_FALSE) - { - CloseLib(fsynth_handle); - fsynth_handle = NULL; - } - } - return ret; -} -#else -static inline ALboolean LoadFSynth(void) { return AL_TRUE; } -#endif - - -/* MIDI events */ -#define SYSEX_EVENT (0xF0) - -/* MIDI controllers */ -#define CTRL_BANKSELECT_MSB (0) -#define CTRL_BANKSELECT_LSB (32) -#define CTRL_ALLNOTESOFF (123) - - -static int getModInput(ALenum input) -{ - switch(input) - { - case AL_ONE_SOFT: return FLUID_MOD_NONE; - case AL_NOTEON_VELOCITY_SOFT: return FLUID_MOD_VELOCITY; - case AL_NOTEON_KEY_SOFT: return FLUID_MOD_KEY; - case AL_KEYPRESSURE_SOFT: return FLUID_MOD_KEYPRESSURE; - case AL_CHANNELPRESSURE_SOFT: return FLUID_MOD_CHANNELPRESSURE; - case AL_PITCHBEND_SOFT: return FLUID_MOD_PITCHWHEEL; - case AL_PITCHBEND_SENSITIVITY_SOFT: return FLUID_MOD_PITCHWHEELSENS; - } - return input&0x7F; -} - -static int getModFlags(ALenum input, ALenum type, ALenum form) -{ - int ret = 0; - - switch(type) - { - case AL_UNORM_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE; break; - case AL_UNORM_REV_SOFT: ret |= FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE; break; - case AL_SNORM_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE; break; - case AL_SNORM_REV_SOFT: ret |= FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE; break; - } - switch(form) - { - case AL_LINEAR_SOFT: ret |= FLUID_MOD_LINEAR; break; - case AL_CONCAVE_SOFT: ret |= FLUID_MOD_CONCAVE; break; - case AL_CONVEX_SOFT: ret |= FLUID_MOD_CONVEX; break; - case AL_SWITCH_SOFT: ret |= FLUID_MOD_SWITCH; break; - } - /* Source input values less than 128 correspond to a MIDI continuous - * controller. Otherwise, it's a general controller. */ - if(input < 128) ret |= FLUID_MOD_CC; - else ret |= FLUID_MOD_GC; - - return ret; -} - -static enum fluid_gen_type getModDest(ALenum gen) -{ - switch(gen) - { - case AL_MOD_LFO_TO_PITCH_SOFT: return GEN_MODLFOTOPITCH; - case AL_VIBRATO_LFO_TO_PITCH_SOFT: return GEN_VIBLFOTOPITCH; - case AL_MOD_ENV_TO_PITCH_SOFT: return GEN_MODENVTOPITCH; - case AL_FILTER_CUTOFF_SOFT: return GEN_FILTERFC; - case AL_FILTER_RESONANCE_SOFT: return GEN_FILTERQ; - case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: return GEN_MODLFOTOFILTERFC; - case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: return GEN_MODENVTOFILTERFC; - case AL_MOD_LFO_TO_VOLUME_SOFT: return GEN_MODLFOTOVOL; - case AL_CHORUS_SEND_SOFT: return GEN_CHORUSSEND; - case AL_REVERB_SEND_SOFT: return GEN_REVERBSEND; - case AL_PAN_SOFT: return GEN_PAN; - case AL_MOD_LFO_DELAY_SOFT: return GEN_MODLFODELAY; - case AL_MOD_LFO_FREQUENCY_SOFT: return GEN_MODLFOFREQ; - case AL_VIBRATO_LFO_DELAY_SOFT: return GEN_VIBLFODELAY; - case AL_VIBRATO_LFO_FREQUENCY_SOFT: return GEN_VIBLFOFREQ; - case AL_MOD_ENV_DELAYTIME_SOFT: return GEN_MODENVDELAY; - case AL_MOD_ENV_ATTACKTIME_SOFT: return GEN_MODENVATTACK; - case AL_MOD_ENV_HOLDTIME_SOFT: return GEN_MODENVHOLD; - case AL_MOD_ENV_DECAYTIME_SOFT: return GEN_MODENVDECAY; - case AL_MOD_ENV_SUSTAINVOLUME_SOFT: return GEN_MODENVSUSTAIN; - case AL_MOD_ENV_RELEASETIME_SOFT: return GEN_MODENVRELEASE; - case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOMODENVHOLD; - case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOMODENVDECAY; - case AL_VOLUME_ENV_DELAYTIME_SOFT: return GEN_VOLENVDELAY; - case AL_VOLUME_ENV_ATTACKTIME_SOFT: return GEN_VOLENVATTACK; - case AL_VOLUME_ENV_HOLDTIME_SOFT: return GEN_VOLENVHOLD; - case AL_VOLUME_ENV_DECAYTIME_SOFT: return GEN_VOLENVDECAY; - case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: return GEN_VOLENVSUSTAIN; - case AL_VOLUME_ENV_RELEASETIME_SOFT: return GEN_VOLENVRELEASE; - case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: return GEN_KEYTOVOLENVHOLD; - case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: return GEN_KEYTOVOLENVDECAY; - case AL_ATTENUATION_SOFT: return GEN_ATTENUATION; - case AL_TUNING_COARSE_SOFT: return GEN_COARSETUNE; - case AL_TUNING_FINE_SOFT: return GEN_FINETUNE; - case AL_TUNING_SCALE_SOFT: return GEN_SCALETUNE; - } - ERR("Unhandled generator: 0x%04x\n", gen); - return 0; -} - -static int getSf2LoopMode(ALenum mode) -{ - switch(mode) - { - case AL_NONE: return 0; - case AL_LOOP_CONTINUOUS_SOFT: return 1; - case AL_LOOP_UNTIL_RELEASE_SOFT: return 3; - } - return 0; -} - -static int getSampleType(ALenum type) -{ - switch(type) - { - case AL_MONO_SOFT: return FLUID_SAMPLETYPE_MONO; - case AL_RIGHT_SOFT: return FLUID_SAMPLETYPE_RIGHT; - case AL_LEFT_SOFT: return FLUID_SAMPLETYPE_LEFT; - } - return FLUID_SAMPLETYPE_MONO; -} - -typedef struct FSample { - DERIVE_FROM_TYPE(fluid_sample_t); - - ALfontsound *Sound; - - fluid_mod_t *Mods; - ALsizei NumMods; -} FSample; - -static void FSample_Construct(FSample *self, ALfontsound *sound) -{ - fluid_sample_t *sample = STATIC_CAST(fluid_sample_t, self); - memset(sample->name, 0, sizeof(sample->name)); - sample->start = sound->Start; - sample->end = sound->End; - sample->loopstart = sound->LoopStart; - sample->loopend = sound->LoopEnd; - sample->samplerate = sound->SampleRate; - sample->origpitch = sound->PitchKey; - sample->pitchadj = sound->PitchCorrection; - sample->sampletype = getSampleType(sound->SampleType); - sample->valid = !!sound->Buffer; - sample->data = sound->Buffer ? sound->Buffer->data : NULL; - - sample->amplitude_that_reaches_noise_floor_is_valid = 0; - sample->amplitude_that_reaches_noise_floor = 0.0; - - sample->refcount = 0; - - sample->notify = NULL; - - sample->userdata = self; - - self->Sound = sound; - - self->NumMods = 0; - self->Mods = calloc(sound->ModulatorMap.size*4, sizeof(fluid_mod_t[4])); - if(self->Mods) - { - ALsizei i, j, k; - - for(i = j = 0;i < sound->ModulatorMap.size;i++) - { - ALsfmodulator *mod = sound->ModulatorMap.array[i].value; - for(k = 0;k < 4;k++,mod++) - { - if(mod->Dest == AL_NONE) - continue; - fluid_mod_set_source1(&self->Mods[j], getModInput(mod->Source[0].Input), - getModFlags(mod->Source[0].Input, mod->Source[0].Type, - mod->Source[0].Form)); - fluid_mod_set_source2(&self->Mods[j], getModInput(mod->Source[1].Input), - getModFlags(mod->Source[1].Input, mod->Source[1].Type, - mod->Source[1].Form)); - fluid_mod_set_amount(&self->Mods[j], mod->Amount); - fluid_mod_set_dest(&self->Mods[j], getModDest(mod->Dest)); - self->Mods[j++].next = NULL; - } - } - self->NumMods = j; - } -} - -static void FSample_Destruct(FSample *self) -{ - free(self->Mods); - self->Mods = NULL; - self->NumMods = 0; -} - - -typedef struct FPreset { - DERIVE_FROM_TYPE(fluid_preset_t); - - char Name[16]; - - int Preset; - int Bank; - - FSample *Samples; - ALsizei NumSamples; -} FPreset; - -static char* FPreset_getName(fluid_preset_t *preset); -static int FPreset_getPreset(fluid_preset_t *preset); -static int FPreset_getBank(fluid_preset_t *preset); -static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int velocity); - -static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *parent) -{ - STATIC_CAST(fluid_preset_t, self)->data = self; - STATIC_CAST(fluid_preset_t, self)->sfont = parent; - STATIC_CAST(fluid_preset_t, self)->free = NULL; - STATIC_CAST(fluid_preset_t, self)->get_name = FPreset_getName; - STATIC_CAST(fluid_preset_t, self)->get_banknum = FPreset_getBank; - STATIC_CAST(fluid_preset_t, self)->get_num = FPreset_getPreset; - STATIC_CAST(fluid_preset_t, self)->noteon = FPreset_noteOn; - STATIC_CAST(fluid_preset_t, self)->notify = NULL; - - memset(self->Name, 0, sizeof(self->Name)); - self->Preset = preset->Preset; - self->Bank = preset->Bank; - - self->NumSamples = 0; - self->Samples = calloc(1, preset->NumSounds * sizeof(self->Samples[0])); - if(self->Samples) - { - ALsizei i; - self->NumSamples = preset->NumSounds; - for(i = 0;i < self->NumSamples;i++) - FSample_Construct(&self->Samples[i], preset->Sounds[i]); - } -} - -static void FPreset_Destruct(FPreset *self) -{ - ALsizei i; - - for(i = 0;i < self->NumSamples;i++) - FSample_Destruct(&self->Samples[i]); - free(self->Samples); - self->Samples = NULL; - self->NumSamples = 0; -} - -static ALboolean FPreset_canDelete(FPreset *self) -{ - ALsizei i; - for(i = 0;i < self->NumSamples;i++) - { - if(fluid_sample_refcount(STATIC_CAST(fluid_sample_t, &self->Samples[i])) != 0) - return AL_FALSE; - } - return AL_TRUE; -} - -static char* FPreset_getName(fluid_preset_t *preset) -{ - return ((FPreset*)preset->data)->Name; -} - -static int FPreset_getPreset(fluid_preset_t *preset) -{ - return ((FPreset*)preset->data)->Preset; -} - -static int FPreset_getBank(fluid_preset_t *preset) -{ - return ((FPreset*)preset->data)->Bank; -} - -static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int vel) -{ - FPreset *self = ((FPreset*)preset->data); - ALsizei i; - - for(i = 0;i < self->NumSamples;i++) - { - FSample *sample = &self->Samples[i]; - ALfontsound *sound = sample->Sound; - fluid_voice_t *voice; - ALsizei m; - - if(!(key >= sound->MinKey && key <= sound->MaxKey && vel >= sound->MinVelocity && vel <= sound->MaxVelocity)) - continue; - - voice = fluid_synth_alloc_voice(synth, STATIC_CAST(fluid_sample_t, sample), channel, key, vel); - if(voice == NULL) return FLUID_FAILED; - - fluid_voice_gen_set(voice, GEN_MODLFOTOPITCH, sound->ModLfoToPitch); - fluid_voice_gen_set(voice, GEN_VIBLFOTOPITCH, sound->VibratoLfoToPitch); - fluid_voice_gen_set(voice, GEN_MODENVTOPITCH, sound->ModEnvToPitch); - fluid_voice_gen_set(voice, GEN_FILTERFC, sound->FilterCutoff); - fluid_voice_gen_set(voice, GEN_FILTERQ, sound->FilterQ); - fluid_voice_gen_set(voice, GEN_MODLFOTOFILTERFC, sound->ModLfoToFilterCutoff); - fluid_voice_gen_set(voice, GEN_MODENVTOFILTERFC, sound->ModEnvToFilterCutoff); - fluid_voice_gen_set(voice, GEN_MODLFOTOVOL, sound->ModLfoToVolume); - fluid_voice_gen_set(voice, GEN_CHORUSSEND, sound->ChorusSend); - fluid_voice_gen_set(voice, GEN_REVERBSEND, sound->ReverbSend); - fluid_voice_gen_set(voice, GEN_PAN, sound->Pan); - fluid_voice_gen_set(voice, GEN_MODLFODELAY, sound->ModLfo.Delay); - fluid_voice_gen_set(voice, GEN_MODLFOFREQ, sound->ModLfo.Frequency); - fluid_voice_gen_set(voice, GEN_VIBLFODELAY, sound->VibratoLfo.Delay); - fluid_voice_gen_set(voice, GEN_VIBLFOFREQ, sound->VibratoLfo.Frequency); - fluid_voice_gen_set(voice, GEN_MODENVDELAY, sound->ModEnv.DelayTime); - fluid_voice_gen_set(voice, GEN_MODENVATTACK, sound->ModEnv.AttackTime); - fluid_voice_gen_set(voice, GEN_MODENVHOLD, sound->ModEnv.HoldTime); - fluid_voice_gen_set(voice, GEN_MODENVDECAY, sound->ModEnv.DecayTime); - fluid_voice_gen_set(voice, GEN_MODENVSUSTAIN, sound->ModEnv.SustainAttn); - fluid_voice_gen_set(voice, GEN_MODENVRELEASE, sound->ModEnv.ReleaseTime); - fluid_voice_gen_set(voice, GEN_KEYTOMODENVHOLD, sound->ModEnv.KeyToHoldTime); - fluid_voice_gen_set(voice, GEN_KEYTOMODENVDECAY, sound->ModEnv.KeyToDecayTime); - fluid_voice_gen_set(voice, GEN_VOLENVDELAY, sound->VolEnv.DelayTime); - fluid_voice_gen_set(voice, GEN_VOLENVATTACK, sound->VolEnv.AttackTime); - fluid_voice_gen_set(voice, GEN_VOLENVHOLD, sound->VolEnv.HoldTime); - fluid_voice_gen_set(voice, GEN_VOLENVDECAY, sound->VolEnv.DecayTime); - fluid_voice_gen_set(voice, GEN_VOLENVSUSTAIN, sound->VolEnv.SustainAttn); - fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, sound->VolEnv.ReleaseTime); - fluid_voice_gen_set(voice, GEN_KEYTOVOLENVHOLD, sound->VolEnv.KeyToHoldTime); - fluid_voice_gen_set(voice, GEN_KEYTOVOLENVDECAY, sound->VolEnv.KeyToDecayTime); - fluid_voice_gen_set(voice, GEN_ATTENUATION, sound->Attenuation); - fluid_voice_gen_set(voice, GEN_COARSETUNE, sound->CoarseTuning); - fluid_voice_gen_set(voice, GEN_FINETUNE, sound->FineTuning); - fluid_voice_gen_set(voice, GEN_SAMPLEMODE, getSf2LoopMode(sound->LoopMode)); - fluid_voice_gen_set(voice, GEN_SCALETUNE, sound->TuningScale); - fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, sound->ExclusiveClass); - for(m = 0;m < sample->NumMods;m++) - fluid_voice_add_mod(voice, &sample->Mods[m], FLUID_VOICE_OVERWRITE); - - fluid_synth_start_voice(synth, voice); - } - - return FLUID_OK; -} - - -typedef struct FSfont { - DERIVE_FROM_TYPE(fluid_sfont_t); - - char Name[16]; - - FPreset *Presets; - ALsizei NumPresets; - - ALsizei CurrentPos; -} FSfont; - -static int FSfont_free(fluid_sfont_t *sfont); -static char* FSfont_getName(fluid_sfont_t *sfont); -static fluid_preset_t* FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum); -static void FSfont_iterStart(fluid_sfont_t *sfont); -static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset); - -static void FSfont_Construct(FSfont *self, ALsoundfont *sfont) -{ - STATIC_CAST(fluid_sfont_t, self)->data = self; - STATIC_CAST(fluid_sfont_t, self)->id = FLUID_FAILED; - STATIC_CAST(fluid_sfont_t, self)->free = FSfont_free; - STATIC_CAST(fluid_sfont_t, self)->get_name = FSfont_getName; - STATIC_CAST(fluid_sfont_t, self)->get_preset = FSfont_getPreset; - STATIC_CAST(fluid_sfont_t, self)->iteration_start = FSfont_iterStart; - STATIC_CAST(fluid_sfont_t, self)->iteration_next = FSfont_iterNext; - - memset(self->Name, 0, sizeof(self->Name)); - self->CurrentPos = 0; - self->NumPresets = 0; - self->Presets = calloc(1, sfont->NumPresets * sizeof(self->Presets[0])); - if(self->Presets) - { - ALsizei i; - self->NumPresets = sfont->NumPresets; - for(i = 0;i < self->NumPresets;i++) - FPreset_Construct(&self->Presets[i], sfont->Presets[i], STATIC_CAST(fluid_sfont_t, self)); - } -} - -static void FSfont_Destruct(FSfont *self) -{ - ALsizei i; - - for(i = 0;i < self->NumPresets;i++) - FPreset_Destruct(&self->Presets[i]); - free(self->Presets); - self->Presets = NULL; - self->NumPresets = 0; - self->CurrentPos = 0; -} - -static int FSfont_free(fluid_sfont_t *sfont) -{ - FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); - ALsizei i; - - for(i = 0;i < self->NumPresets;i++) - { - if(!FPreset_canDelete(&self->Presets[i])) - return 1; - } - - FSfont_Destruct(self); - free(self); - return 0; -} - -static char* FSfont_getName(fluid_sfont_t *sfont) -{ - return STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->Name; -} - -static fluid_preset_t *FSfont_getPreset(fluid_sfont_t *sfont, unsigned int bank, unsigned int prenum) -{ - FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); - ALsizei i; - - for(i = 0;i < self->NumPresets;i++) - { - FPreset *preset = &self->Presets[i]; - if(preset->Bank == (int)bank && preset->Preset == (int)prenum) - return STATIC_CAST(fluid_preset_t, preset); - } - - return NULL; -} - -static void FSfont_iterStart(fluid_sfont_t *sfont) -{ - STATIC_UPCAST(FSfont, fluid_sfont_t, sfont)->CurrentPos = 0; -} - -static int FSfont_iterNext(fluid_sfont_t *sfont, fluid_preset_t *preset) -{ - FSfont *self = STATIC_UPCAST(FSfont, fluid_sfont_t, sfont); - if(self->CurrentPos >= self->NumPresets) - return 0; - *preset = *STATIC_CAST(fluid_preset_t, &self->Presets[self->CurrentPos++]); - preset->free = NULL; - return 1; -} - - -typedef struct FSynth { - DERIVE_FROM_TYPE(MidiSynth); - DERIVE_FROM_TYPE(fluid_sfloader_t); - - fluid_settings_t *Settings; - fluid_synth_t *Synth; - int *FontIDs; - ALsizei NumFontIDs; - - ALboolean ForceGM2BankSelect; - ALfloat GainScale; -} FSynth; - -static void FSynth_Construct(FSynth *self, ALCdevice *device); -static void FSynth_Destruct(FSynth *self); -static ALboolean FSynth_init(FSynth *self, ALCdevice *device); -static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids); -static void FSynth_setGain(FSynth *self, ALfloat gain); -static void FSynth_stop(FSynth *self); -static void FSynth_reset(FSynth *self); -static void FSynth_update(FSynth *self, ALCdevice *device); -static void FSynth_processQueue(FSynth *self, ALuint64 time); -static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); -DECLARE_DEFAULT_ALLOCATORS(FSynth) -DEFINE_MIDISYNTH_VTABLE(FSynth); - -static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename); - - -static void FSynth_Construct(FSynth *self, ALCdevice *device) -{ - MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device); - SET_VTABLE2(FSynth, MidiSynth, self); - - STATIC_CAST(fluid_sfloader_t, self)->data = self; - STATIC_CAST(fluid_sfloader_t, self)->free = NULL; - STATIC_CAST(fluid_sfloader_t, self)->load = FSynth_loadSfont; - - self->Settings = NULL; - self->Synth = NULL; - self->FontIDs = NULL; - self->NumFontIDs = 0; - self->ForceGM2BankSelect = AL_FALSE; - self->GainScale = 0.2f; -} - -static void FSynth_Destruct(FSynth *self) -{ - ALsizei i; - - for(i = 0;i < self->NumFontIDs;i++) - fluid_synth_sfunload(self->Synth, self->FontIDs[i], 0); - free(self->FontIDs); - self->FontIDs = NULL; - self->NumFontIDs = 0; - - if(self->Synth != NULL) - delete_fluid_synth(self->Synth); - self->Synth = NULL; - - if(self->Settings != NULL) - delete_fluid_settings(self->Settings); - self->Settings = NULL; - - MidiSynth_Destruct(STATIC_CAST(MidiSynth, self)); -} - -static ALboolean FSynth_init(FSynth *self, ALCdevice *device) -{ - ALfloat vol; - - if(ConfigValueFloat("midi", "volume", &vol)) - { - if(!(vol <= 0.0f)) - { - ERR("MIDI volume %f clamped to 0\n", vol); - vol = 0.0f; - } - self->GainScale = powf(10.0f, vol / 20.0f); - } - - self->Settings = new_fluid_settings(); - if(!self->Settings) - { - ERR("Failed to create FluidSettings\n"); - return AL_FALSE; - } - - fluid_settings_setint(self->Settings, "synth.polyphony", 256); - fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale); - fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency); - - self->Synth = new_fluid_synth(self->Settings); - if(!self->Synth) - { - ERR("Failed to create FluidSynth\n"); - return AL_FALSE; - } - - fluid_synth_add_sfloader(self->Synth, STATIC_CAST(fluid_sfloader_t, self)); - - return AL_TRUE; -} - - -static fluid_sfont_t *FSynth_loadSfont(fluid_sfloader_t *loader, const char *filename) -{ - FSynth *self = STATIC_UPCAST(FSynth, fluid_sfloader_t, loader); - FSfont *sfont; - int idx; - - if(!filename || sscanf(filename, "_al_internal %d", &idx) != 1) - return NULL; - if(idx < 0 || idx >= STATIC_CAST(MidiSynth, self)->NumSoundfonts) - { - ERR("Received invalid soundfont index %d (max: %d)\n", idx, STATIC_CAST(MidiSynth, self)->NumSoundfonts); - return NULL; - } - - sfont = calloc(1, sizeof(sfont[0])); - if(!sfont) return NULL; - - FSfont_Construct(sfont, STATIC_CAST(MidiSynth, self)->Soundfonts[idx]); - return STATIC_CAST(fluid_sfont_t, sfont); -} - -static ALenum FSynth_selectSoundfonts(FSynth *self, ALCcontext *context, ALsizei count, const ALuint *ids) -{ - int *fontid; - ALenum ret; - ALsizei i; - - ret = MidiSynth_selectSoundfonts(STATIC_CAST(MidiSynth, self), context, count, ids); - if(ret != AL_NO_ERROR) return ret; - - ALCdevice_Lock(context->Device); - for(i = 0;i < 16;i++) - fluid_synth_all_sounds_off(self->Synth, i); - ALCdevice_Unlock(context->Device); - - fontid = malloc(count * sizeof(fontid[0])); - if(fontid) - { - for(i = 0;i < STATIC_CAST(MidiSynth, self)->NumSoundfonts;i++) - { - char name[16]; - snprintf(name, sizeof(name), "_al_internal %d", i); - - fontid[i] = fluid_synth_sfload(self->Synth, name, 0); - if(fontid[i] == FLUID_FAILED) - ERR("Failed to load selected soundfont %d\n", i); - } - - fontid = ExchangePtr((XchgPtr*)&self->FontIDs, fontid); - count = ExchangeInt(&self->NumFontIDs, count); - } - else - { - ERR("Failed to allocate space for %d font IDs!\n", count); - fontid = ExchangePtr((XchgPtr*)&self->FontIDs, NULL); - count = ExchangeInt(&self->NumFontIDs, 0); - } - - for(i = 0;i < count;i++) - fluid_synth_sfunload(self->Synth, fontid[i], 0); - free(fontid); - - return ret; -} - - -static void FSynth_setGain(FSynth *self, ALfloat gain) -{ - fluid_settings_setnum(self->Settings, "synth.gain", self->GainScale * gain); - fluid_synth_set_gain(self->Synth, self->GainScale * gain); - MidiSynth_setGain(STATIC_CAST(MidiSynth, self), gain); -} - - -static void FSynth_stop(FSynth *self) -{ - MidiSynth *synth = STATIC_CAST(MidiSynth, self); - ALuint64 curtime; - ALsizei chan; - - /* Make sure all pending events are processed. */ - curtime = MidiSynth_getTime(synth); - FSynth_processQueue(self, curtime); - - /* All notes off */ - for(chan = 0;chan < 16;chan++) - fluid_synth_cc(self->Synth, chan, CTRL_ALLNOTESOFF, 0); - - MidiSynth_stop(STATIC_CAST(MidiSynth, self)); -} - -static void FSynth_reset(FSynth *self) -{ - /* Reset to power-up status. */ - fluid_synth_system_reset(self->Synth); - - MidiSynth_reset(STATIC_CAST(MidiSynth, self)); -} - - -static void FSynth_update(FSynth *self, ALCdevice *device) -{ - fluid_settings_setnum(self->Settings, "synth.sample-rate", device->Frequency); - fluid_synth_set_sample_rate(self->Synth, device->Frequency); - MidiSynth_update(STATIC_CAST(MidiSynth, self), device); -} - - -static void FSynth_processQueue(FSynth *self, ALuint64 time) -{ - EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; - - while(queue->pos < queue->size && queue->events[queue->pos].time <= time) - { - const MidiEvent *evt = &queue->events[queue->pos]; - - if(evt->event == SYSEX_EVENT) - { - static const ALbyte gm2_on[] = { 0x7E, 0x7F, 0x09, 0x03 }; - static const ALbyte gm2_off[] = { 0x7E, 0x7F, 0x09, 0x02 }; - int handled = 0; - - fluid_synth_sysex(self->Synth, evt->param.sysex.data, evt->param.sysex.size, NULL, NULL, &handled, 0); - if(!handled && evt->param.sysex.size >= (ALsizei)sizeof(gm2_on)) - { - if(memcmp(evt->param.sysex.data, gm2_on, sizeof(gm2_on)) == 0) - self->ForceGM2BankSelect = AL_TRUE; - else if(memcmp(evt->param.sysex.data, gm2_off, sizeof(gm2_off)) == 0) - self->ForceGM2BankSelect = AL_FALSE; - } - } - else switch((evt->event&0xF0)) - { - case AL_NOTEOFF_SOFT: - fluid_synth_noteoff(self->Synth, (evt->event&0x0F), evt->param.val[0]); - break; - case AL_NOTEON_SOFT: - fluid_synth_noteon(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); - break; - case AL_KEYPRESSURE_SOFT: - break; - - case AL_CONTROLLERCHANGE_SOFT: - if(self->ForceGM2BankSelect) - { - int chan = (evt->event&0x0F); - if(evt->param.val[0] == CTRL_BANKSELECT_MSB) - { - if(evt->param.val[1] == 120 && (chan == 9 || chan == 10)) - fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_DRUM); - else if(evt->param.val[1] == 121) - fluid_synth_set_channel_type(self->Synth, chan, CHANNEL_TYPE_MELODIC); - break; - } - if(evt->param.val[0] == CTRL_BANKSELECT_LSB) - { - fluid_synth_bank_select(self->Synth, chan, evt->param.val[1]); - break; - } - } - fluid_synth_cc(self->Synth, (evt->event&0x0F), evt->param.val[0], evt->param.val[1]); - break; - case AL_PROGRAMCHANGE_SOFT: - fluid_synth_program_change(self->Synth, (evt->event&0x0F), evt->param.val[0]); - break; - - case AL_CHANNELPRESSURE_SOFT: - fluid_synth_channel_pressure(self->Synth, (evt->event&0x0F), evt->param.val[0]); - break; - - case AL_PITCHBEND_SOFT: - fluid_synth_pitch_bend(self->Synth, (evt->event&0x0F), (evt->param.val[0]&0x7F) | - ((evt->param.val[1]&0x7F)<<7)); - break; - } - - queue->pos++; - } -} - -static void FSynth_process(FSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]) -{ - MidiSynth *synth = STATIC_CAST(MidiSynth, self); - ALenum state = synth->State; - ALuint64 curtime; - ALuint total = 0; - - if(state == AL_INITIAL) - return; - if(state != AL_PLAYING) - { - fluid_synth_write_float(self->Synth, SamplesToDo, DryBuffer[FrontLeft], 0, 1, - DryBuffer[FrontRight], 0, 1); - return; - } - - curtime = MidiSynth_getTime(synth); - while(total < SamplesToDo) - { - ALuint64 time, diff; - ALint tonext; - - time = MidiSynth_getNextEvtTime(synth); - diff = maxu64(time, curtime) - curtime; - if(diff >= MIDI_CLOCK_RES || time == UINT64_MAX) - { - /* If there's no pending event, or if it's more than 1 second - * away, do as many samples as we can. */ - tonext = INT_MAX; - } - else - { - /* Figure out how many samples until the next event. */ - tonext = (ALint)((diff*synth->SampleRate + (MIDI_CLOCK_RES-1)) / MIDI_CLOCK_RES); - tonext -= total; - } - - if(tonext > 0) - { - ALuint todo = minu(tonext, SamplesToDo-total); - fluid_synth_write_float(self->Synth, todo, DryBuffer[FrontLeft], total, 1, - DryBuffer[FrontRight], total, 1); - total += todo; - tonext -= todo; - } - if(total < SamplesToDo && tonext <= 0) - FSynth_processQueue(self, time); - } - - synth->SamplesDone += SamplesToDo; - synth->ClockBase += (synth->SamplesDone/synth->SampleRate) * MIDI_CLOCK_RES; - synth->SamplesDone %= synth->SampleRate; -} - - -MidiSynth *FSynth_create(ALCdevice *device) -{ - FSynth *synth; - - if(!LoadFSynth()) - return NULL; - - synth = FSynth_New(sizeof(*synth)); - if(!synth) - { - ERR("Failed to allocate FSynth\n"); - return NULL; - } - memset(synth, 0, sizeof(*synth)); - FSynth_Construct(synth, device); - - if(FSynth_init(synth, device) == AL_FALSE) - { - DELETE_OBJ(STATIC_CAST(MidiSynth, synth)); - return NULL; - } - - return STATIC_CAST(MidiSynth, synth); -} - -#else - -MidiSynth *FSynth_create(ALCdevice* UNUSED(device)) -{ - return NULL; -} - -#endif diff --git a/love/src/jni/openal-soft-1.17.0/Alc/midi/sf2load.c b/love/src/jni/openal-soft-1.17.0/Alc/midi/sf2load.c deleted file mode 100644 index 233f7983..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/midi/sf2load.c +++ /dev/null @@ -1,1377 +0,0 @@ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alMidi.h" -#include "alError.h" -#include "alu.h" - -#include "midi/base.h" - - -static ALuint read_le32(Reader *stream) -{ - ALubyte buf[4]; - if(Reader_read(stream, buf, 4) != 4) - return 0; - return (buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0]; -} -static ALushort read_le16(Reader *stream) -{ - ALubyte buf[2]; - if(Reader_read(stream, buf, 2) != 2) - return 0; - return (buf[1]<<8) | buf[0]; -} -static ALubyte read_8(Reader *stream) -{ - ALubyte buf[1]; - if(Reader_read(stream, buf, 1) != 1) - return 0; - return buf[0]; -} -static void skip(Reader *stream, ALuint amt) -{ - while(amt > 0 && !READERR(stream)) - { - char buf[4096]; - amt -= Reader_read(stream, buf, minu(sizeof(buf), amt)); - } -} - -typedef struct Generator { - ALushort mGenerator; - ALushort mAmount; -} Generator; -static void Generator_read(Generator *self, Reader *stream) -{ - self->mGenerator = read_le16(stream); - self->mAmount = read_le16(stream); -} - -static const ALint DefaultGenValue[60] = { - 0, /* 0 - startAddrOffset */ - 0, /* 1 - endAddrOffset */ - 0, /* 2 - startloopAddrOffset */ - 0, /* 3 - endloopAddrOffset */ - 0, /* 4 - startAddrCoarseOffset */ - 0, /* 5 - modLfoToPitch */ - 0, /* 6 - vibLfoToPitch */ - 0, /* 7 - modEnvToPitch */ - 13500, /* 8 - initialFilterFc */ - 0, /* 9 - initialFilterQ */ - 0, /* 10 - modLfoToFilterFc */ - 0, /* 11 - modEnvToFilterFc */ - 0, /* 12 - endAddrCoarseOffset */ - 0, /* 13 - modLfoToVolume */ - 0, /* 14 - */ - 0, /* 15 - chorusEffectsSend */ - 0, /* 16 - reverbEffectsSend */ - 0, /* 17 - pan */ - 0, /* 18 - */ - 0, /* 19 - */ - 0, /* 20 - */ - -12000, /* 21 - delayModLFO */ - 0, /* 22 - freqModLFO */ - -12000, /* 23 - delayVibLFO */ - 0, /* 24 - freqVibLFO */ - -12000, /* 25 - delayModEnv */ - -12000, /* 26 - attackModEnv */ - -12000, /* 27 - holdModEnv */ - -12000, /* 28 - decayModEnv */ - 0, /* 29 - sustainModEnv */ - -12000, /* 30 - releaseModEnv */ - 0, /* 31 - keynumToModEnvHold */ - 0, /* 32 - keynumToModEnvDecay */ - -12000, /* 33 - delayVolEnv */ - -12000, /* 34 - attackVolEnv */ - -12000, /* 35 - holdVolEnv */ - -12000, /* 36 - decayVolEnv */ - 0, /* 37 - sustainVolEnv */ - -12000, /* 38 - releaseVolEnv */ - 0, /* 39 - keynumToVolEnvHold */ - 0, /* 40 - keynumToVolEnvDecay */ - 0, /* 41 - */ - 0, /* 42 - */ - 0, /* 43 - keyRange */ - 0, /* 44 - velRange */ - 0, /* 45 - startloopAddrCoarseOffset */ - 0, /* 46 - keynum */ - 0, /* 47 - velocity */ - 0, /* 48 - initialAttenuation */ - 0, /* 49 - */ - 0, /* 50 - endloopAddrCoarseOffset */ - 0, /* 51 - corseTune */ - 0, /* 52 - fineTune */ - 0, /* 53 - */ - 0, /* 54 - sampleModes */ - 0, /* 55 - */ - 100, /* 56 - scaleTuning */ - 0, /* 57 - exclusiveClass */ - 0, /* 58 - overridingRootKey */ - 0, /* 59 - */ -}; - -typedef struct Modulator { - ALushort mSrcOp; - ALushort mDstOp; - ALshort mAmount; - ALushort mAmtSrcOp; - ALushort mTransOp; -} Modulator; -static void Modulator_read(Modulator *self, Reader *stream) -{ - self->mSrcOp = read_le16(stream); - self->mDstOp = read_le16(stream); - self->mAmount = read_le16(stream); - self->mAmtSrcOp = read_le16(stream); - self->mTransOp = read_le16(stream); -} - -typedef struct Zone { - ALushort mGenIdx; - ALushort mModIdx; -} Zone; -static void Zone_read(Zone *self, Reader *stream) -{ - self->mGenIdx = read_le16(stream); - self->mModIdx = read_le16(stream); -} - -typedef struct PresetHeader { - ALchar mName[20]; - ALushort mPreset; /* MIDI program number */ - ALushort mBank; - ALushort mZoneIdx; - ALuint mLibrary; - ALuint mGenre; - ALuint mMorphology; -} PresetHeader; -static void PresetHeader_read(PresetHeader *self, Reader *stream) -{ - Reader_read(stream, self->mName, sizeof(self->mName)); - self->mPreset = read_le16(stream); - self->mBank = read_le16(stream); - self->mZoneIdx = read_le16(stream); - self->mLibrary = read_le32(stream); - self->mGenre = read_le32(stream); - self->mMorphology = read_le32(stream); -} - -typedef struct InstrumentHeader { - ALchar mName[20]; - ALushort mZoneIdx; -} InstrumentHeader; -static void InstrumentHeader_read(InstrumentHeader *self, Reader *stream) -{ - Reader_read(stream, self->mName, sizeof(self->mName)); - self->mZoneIdx = read_le16(stream); -} - -typedef struct SampleHeader { - ALchar mName[20]; - ALuint mStart; - ALuint mEnd; - ALuint mStartloop; - ALuint mEndloop; - ALuint mSampleRate; - ALubyte mOriginalKey; - ALbyte mCorrection; - ALushort mSampleLink; - ALushort mSampleType; -} SampleHeader; -static void SampleHeader_read(SampleHeader *self, Reader *stream) -{ - Reader_read(stream, self->mName, sizeof(self->mName)); - self->mStart = read_le32(stream); - self->mEnd = read_le32(stream); - self->mStartloop = read_le32(stream); - self->mEndloop = read_le32(stream); - self->mSampleRate = read_le32(stream); - self->mOriginalKey = read_8(stream); - self->mCorrection = read_8(stream); - self->mSampleLink = read_le16(stream); - self->mSampleType = read_le16(stream); -} - - -typedef struct Soundfont { - ALuint ifil; - ALchar *irom; - - PresetHeader *phdr; - ALsizei phdr_size; - - Zone *pbag; - ALsizei pbag_size; - Modulator *pmod; - ALsizei pmod_size; - Generator *pgen; - ALsizei pgen_size; - - InstrumentHeader *inst; - ALsizei inst_size; - - Zone *ibag; - ALsizei ibag_size; - Modulator *imod; - ALsizei imod_size; - Generator *igen; - ALsizei igen_size; - - SampleHeader *shdr; - ALsizei shdr_size; -} Soundfont; - -static void Soundfont_Construct(Soundfont *self) -{ - self->ifil = 0; - self->irom = NULL; - - self->phdr = NULL; - self->phdr_size = 0; - - self->pbag = NULL; - self->pbag_size = 0; - self->pmod = NULL; - self->pmod_size = 0; - self->pgen = NULL; - self->pgen_size = 0; - - self->inst = NULL; - self->inst_size = 0; - - self->ibag = NULL; - self->ibag_size = 0; - self->imod = NULL; - self->imod_size = 0; - self->igen = NULL; - self->igen_size = 0; - - self->shdr = NULL; - self->shdr_size = 0; -} - -static void Soundfont_Destruct(Soundfont *self) -{ - free(self->irom); - self->irom = NULL; - - free(self->phdr); - self->phdr = NULL; - self->phdr_size = 0; - - free(self->pbag); - self->pbag = NULL; - self->pbag_size = 0; - free(self->pmod); - self->pmod = NULL; - self->pmod_size = 0; - free(self->pgen); - self->pgen = NULL; - self->pgen_size = 0; - - free(self->inst); - self->inst = NULL; - self->inst_size = 0; - - free(self->ibag); - self->ibag = NULL; - self->ibag_size = 0; - free(self->imod); - self->imod = NULL; - self->imod_size = 0; - free(self->igen); - self->igen = NULL; - self->igen_size = 0; - - free(self->shdr); - self->shdr = NULL; - self->shdr_size = 0; -} - - -#define FOURCC(a,b,c,d) ((a) | ((b)<<8) | ((c)<<16) | ((d)<<24)) -#define FOURCCFMT "%c%c%c%c" -#define FOURCCARGS(x) (char)((x)&0xff), (char)(((x)>>8)&0xff), (char)(((x)>>16)&0xff), (char)(((x)>>24)&0xff) -typedef struct RiffHdr { - ALuint mCode; - ALuint mSize; -} RiffHdr; -static void RiffHdr_read(RiffHdr *self, Reader *stream) -{ - self->mCode = read_le32(stream); - self->mSize = read_le32(stream); -} - - -typedef struct GenModList { - VECTOR(Generator) gens; - VECTOR(Modulator) mods; -} GenModList; - -static void GenModList_Construct(GenModList *self) -{ - VECTOR_INIT(self->gens); - VECTOR_INIT(self->mods); -} - -static void GenModList_Destruct(GenModList *self) -{ - VECTOR_DEINIT(self->mods); - VECTOR_DEINIT(self->gens); -} - -static GenModList GenModList_clone(const GenModList *self) -{ - GenModList ret; - - GenModList_Construct(&ret); - - VECTOR_INSERT(ret.gens, VECTOR_ITER_END(ret.gens), - VECTOR_ITER_BEGIN(self->gens), VECTOR_ITER_END(self->gens) - ); - VECTOR_INSERT(ret.mods, VECTOR_ITER_END(ret.mods), - VECTOR_ITER_BEGIN(self->mods), VECTOR_ITER_END(self->mods) - ); - - return ret; -} - -static void GenModList_insertGen(GenModList *self, const Generator *gen, ALboolean ispreset) -{ - Generator *i = VECTOR_ITER_BEGIN(self->gens); - Generator *end = VECTOR_ITER_END(self->gens); - for(;i != end;i++) - { - if(i->mGenerator == gen->mGenerator) - { - i->mAmount = gen->mAmount; - return; - } - } - - if(ispreset && - (gen->mGenerator == 0 || gen->mGenerator == 1 || gen->mGenerator == 2 || - gen->mGenerator == 3 || gen->mGenerator == 4 || gen->mGenerator == 12 || - gen->mGenerator == 45 || gen->mGenerator == 46 || gen->mGenerator == 47 || - gen->mGenerator == 50 || gen->mGenerator == 54 || gen->mGenerator == 57 || - gen->mGenerator == 58)) - return; - - if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE) - { - ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens)); - return; - } -} -static void GenModList_accumGen(GenModList *self, const Generator *gen) -{ - Generator *i = VECTOR_ITER_BEGIN(self->gens); - Generator *end = VECTOR_ITER_END(self->gens); - for(;i != end;i++) - { - if(i->mGenerator == gen->mGenerator) - { - if(gen->mGenerator == 43 || gen->mGenerator == 44) - { - /* Range generators accumulate by taking the intersection of - * the two ranges. - */ - ALushort low = maxu(i->mAmount&0x00ff, gen->mAmount&0x00ff); - ALushort high = minu(i->mAmount&0xff00, gen->mAmount&0xff00); - i->mAmount = low | high; - } - else - i->mAmount += gen->mAmount; - return; - } - } - - if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE) - { - ERR("Failed to insert generator (from %d elements)\n", VECTOR_SIZE(self->gens)); - return; - } - if(gen->mGenerator < 60) - VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator]; -} - -static void GenModList_insertMod(GenModList *self, const Modulator *mod) -{ - Modulator *i = VECTOR_ITER_BEGIN(self->mods); - Modulator *end = VECTOR_ITER_END(self->mods); - for(;i != end;i++) - { - if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp && - i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp) - { - i->mAmount = mod->mAmount; - return; - } - } - - if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE) - { - ERR("Failed to insert modulator (from %d elements)\n", VECTOR_SIZE(self->mods)); - return; - } -} -static void GenModList_accumMod(GenModList *self, const Modulator *mod) -{ - Modulator *i = VECTOR_ITER_BEGIN(self->mods); - Modulator *end = VECTOR_ITER_END(self->mods); - for(;i != end;i++) - { - if(i->mDstOp == mod->mDstOp && i->mSrcOp == mod->mSrcOp && - i->mAmtSrcOp == mod->mAmtSrcOp && i->mTransOp == mod->mTransOp) - { - i->mAmount += mod->mAmount; - return; - } - } - - if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE) - { - ERR("Failed to insert modulator (from %d elements)\n", VECTOR_SIZE(self->mods)); - return; - } - - if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 960; - else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += -2400; - else if(mod->mSrcOp == 0x000D && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 50; - else if(mod->mSrcOp == 0x0081 && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 50; - else if(mod->mSrcOp == 0x0582 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 960; - else if(mod->mSrcOp == 0x028A && mod->mDstOp == 17 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 1000; - else if(mod->mSrcOp == 0x058B && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 960; - else if(mod->mSrcOp == 0x00DB && mod->mDstOp == 16 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 200; - else if(mod->mSrcOp == 0x00DD && mod->mDstOp == 15 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 200; - /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0) - VECTOR_BACK(self->mods).mAmount += 12700;*/ -} - - -#define ERROR_GOTO(lbl_, ...) do { \ - ERR(__VA_ARGS__); \ - goto lbl_; \ -} while(0) - -static ALboolean ensureFontSanity(const Soundfont *sfont) -{ - ALsizei i; - - for(i = 0;i < sfont->phdr_size;i++) - { - if(sfont->phdr[i].mZoneIdx >= sfont->pbag_size) - { - WARN("Preset %d has invalid zone index %d (max: %d)\n", i, - sfont->phdr[i].mZoneIdx, sfont->pbag_size); - return AL_FALSE; - } - if(i+1 < sfont->phdr_size && sfont->phdr[i+1].mZoneIdx < sfont->phdr[i].mZoneIdx) - { - WARN("Preset %d has invalid zone index (%d does not follow %d)\n", i+1, - sfont->phdr[i+1].mZoneIdx, sfont->phdr[i].mZoneIdx); - return AL_FALSE; - } - } - - for(i = 0;i < sfont->pbag_size;i++) - { - if(sfont->pbag[i].mGenIdx >= sfont->pgen_size) - { - WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i, - sfont->pbag[i].mGenIdx, sfont->pgen_size); - return AL_FALSE; - } - if(i+1 < sfont->pbag_size && sfont->pbag[i+1].mGenIdx < sfont->pbag[i].mGenIdx) - { - WARN("Preset zone %d has invalid generator index (%d does not follow %d)\n", i+1, - sfont->pbag[i+1].mGenIdx, sfont->pbag[i].mGenIdx); - return AL_FALSE; - } - if(sfont->pbag[i].mModIdx >= sfont->pmod_size) - { - WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i, - sfont->pbag[i].mModIdx, sfont->pmod_size); - return AL_FALSE; - } - if(i+1 < sfont->pbag_size && sfont->pbag[i+1].mModIdx < sfont->pbag[i].mModIdx) - { - WARN("Preset zone %d has invalid modulator index (%d does not follow %d)\n", i+1, - sfont->pbag[i+1].mModIdx, sfont->pbag[i].mModIdx); - return AL_FALSE; - } - } - - - for(i = 0;i < sfont->inst_size;i++) - { - if(sfont->inst[i].mZoneIdx >= sfont->ibag_size) - { - WARN("Instrument %d has invalid zone index %d (max: %d)\n", i, - sfont->inst[i].mZoneIdx, sfont->ibag_size); - return AL_FALSE; - } - if(i+1 < sfont->inst_size && sfont->inst[i+1].mZoneIdx < sfont->inst[i].mZoneIdx) - { - WARN("Instrument %d has invalid zone index (%d does not follow %d)\n", i+1, - sfont->inst[i+1].mZoneIdx, sfont->inst[i].mZoneIdx); - return AL_FALSE; - } - } - - for(i = 0;i < sfont->ibag_size;i++) - { - if(sfont->ibag[i].mGenIdx >= sfont->igen_size) - { - WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i, - sfont->ibag[i].mGenIdx, sfont->igen_size); - return AL_FALSE; - } - if(i+1 < sfont->ibag_size && sfont->ibag[i+1].mGenIdx < sfont->ibag[i].mGenIdx) - { - WARN("Instrument zone %d has invalid generator index (%d does not follow %d)\n", i+1, - sfont->ibag[i+1].mGenIdx, sfont->ibag[i].mGenIdx); - return AL_FALSE; - } - if(sfont->ibag[i].mModIdx >= sfont->imod_size) - { - WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i, - sfont->ibag[i].mModIdx, sfont->imod_size); - return AL_FALSE; - } - if(i+1 < sfont->ibag_size && sfont->ibag[i+1].mModIdx < sfont->ibag[i].mModIdx) - { - WARN("Instrument zone %d has invalid modulator index (%d does not follow %d)\n", i+1, - sfont->ibag[i+1].mModIdx, sfont->ibag[i].mModIdx); - return AL_FALSE; - } - } - - - for(i = 0;i < sfont->shdr_size-1;i++) - { - if((sfont->shdr[i].mSampleType&0x8000) && sfont->irom == NULL) - { - WARN("Sample header %d has ROM sample type without an irom sub-chunk\n", i); - return AL_FALSE; - } - } - - - return AL_TRUE; -} - -static ALboolean checkZone(const GenModList *zone, const PresetHeader *preset, const InstrumentHeader *inst, const SampleHeader *samp) -{ - Generator *gen = VECTOR_ITER_BEGIN(zone->gens); - Generator *gen_end = VECTOR_ITER_END(zone->gens); - for(;gen != gen_end;gen++) - { - if(gen->mGenerator == 43 || gen->mGenerator == 44) - { - int high = gen->mAmount>>8; - int low = gen->mAmount&0xff; - - if(!(low >= 0 && high <= 127 && high >= low)) - { - TRACE("Preset \"%s\", inst \"%s\", sample \"%s\": invalid %s range %d...%d\n", - preset->mName, inst->mName, samp->mName, - (gen->mGenerator == 43) ? "key" : - (gen->mGenerator == 44) ? "velocity" : "(unknown)", - low, high); - return AL_FALSE; - } - } - } - - return AL_TRUE; -} - -static ALenum getModSrcInput(int input) -{ - if(input == 0) return AL_ONE_SOFT; - if(input == 2) return AL_NOTEON_VELOCITY_SOFT; - if(input == 3) return AL_NOTEON_KEY_SOFT; - if(input == 10) return AL_KEYPRESSURE_SOFT; - if(input == 13) return AL_CHANNELPRESSURE_SOFT; - if(input == 14) return AL_PITCHBEND_SOFT; - if(input == 16) return AL_PITCHBEND_SENSITIVITY_SOFT; - if((input&0x80)) - { - if(IsValidCtrlInput(input^0x80)) - return input^0x80; - } - ERR("Unhandled modulator source input: 0x%02x\n", input); - return AL_INVALID; -} - -static ALenum getModSrcType(int type) -{ - if(type == 0x0000) return AL_UNORM_SOFT; - if(type == 0x0100) return AL_UNORM_REV_SOFT; - if(type == 0x0200) return AL_SNORM_SOFT; - if(type == 0x0300) return AL_SNORM_REV_SOFT; - ERR("Unhandled modulator source type: 0x%04x\n", type); - return AL_INVALID; -} - -static ALenum getModSrcForm(int form) -{ - if(form == 0x0000) return AL_LINEAR_SOFT; - if(form == 0x0400) return AL_CONCAVE_SOFT; - if(form == 0x0800) return AL_CONVEX_SOFT; - if(form == 0x0C00) return AL_SWITCH_SOFT; - ERR("Unhandled modulator source form: 0x%04x\n", form); - return AL_INVALID; -} - -static ALenum getModTransOp(int op) -{ - if(op == 0) return AL_LINEAR_SOFT; - if(op == 2) return AL_ABSOLUTE_SOFT; - ERR("Unhandled modulator transform op: 0x%04x\n", op); - return AL_INVALID; -} - -static ALenum getLoopMode(int mode) -{ - if(mode == 0) return AL_NONE; - if(mode == 1) return AL_LOOP_CONTINUOUS_SOFT; - if(mode == 3) return AL_LOOP_UNTIL_RELEASE_SOFT; - ERR("Unhandled loop mode: %d\n", mode); - return AL_NONE; -} - -static ALenum getSampleType(int type) -{ - if(type == 1) return AL_MONO_SOFT; - if(type == 2) return AL_RIGHT_SOFT; - if(type == 4) return AL_LEFT_SOFT; - if(type == 8) - { - WARN("Sample type \"linked\" ignored; pretending mono\n"); - return AL_MONO_SOFT; - } - ERR("Unhandled sample type: 0x%04x\n", type); - return AL_MONO_SOFT; -} - -static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *zone) -{ - static const ALenum Gen2Param[60] = { - 0, /* 0 - startAddrOffset */ - 0, /* 1 - endAddrOffset */ - 0, /* 2 - startloopAddrOffset */ - 0, /* 3 - endloopAddrOffset */ - 0, /* 4 - startAddrCoarseOffset */ - AL_MOD_LFO_TO_PITCH_SOFT, /* 5 - modLfoToPitch */ - AL_VIBRATO_LFO_TO_PITCH_SOFT, /* 6 - vibLfoToPitch */ - AL_MOD_ENV_TO_PITCH_SOFT, /* 7 - modEnvToPitch */ - AL_FILTER_CUTOFF_SOFT, /* 8 - initialFilterFc */ - AL_FILTER_RESONANCE_SOFT, /* 9 - initialFilterQ */ - AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT, /* 10 - modLfoToFilterFc */ - AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT, /* 11 - modEnvToFilterFc */ - 0, /* 12 - endAddrCoarseOffset */ - AL_MOD_LFO_TO_VOLUME_SOFT, /* 13 - modLfoToVolume */ - 0, /* 14 - */ - AL_CHORUS_SEND_SOFT, /* 15 - chorusEffectsSend */ - AL_REVERB_SEND_SOFT, /* 16 - reverbEffectsSend */ - AL_PAN_SOFT, /* 17 - pan */ - 0, /* 18 - */ - 0, /* 19 - */ - 0, /* 20 - */ - AL_MOD_LFO_DELAY_SOFT, /* 21 - delayModLFO */ - AL_MOD_LFO_FREQUENCY_SOFT, /* 22 - freqModLFO */ - AL_VIBRATO_LFO_DELAY_SOFT, /* 23 - delayVibLFO */ - AL_VIBRATO_LFO_FREQUENCY_SOFT, /* 24 - freqVibLFO */ - AL_MOD_ENV_DELAYTIME_SOFT, /* 25 - delayModEnv */ - AL_MOD_ENV_ATTACKTIME_SOFT, /* 26 - attackModEnv */ - AL_MOD_ENV_HOLDTIME_SOFT, /* 27 - holdModEnv */ - AL_MOD_ENV_DECAYTIME_SOFT, /* 28 - decayModEnv */ - AL_MOD_ENV_SUSTAINVOLUME_SOFT, /* 29 - sustainModEnv */ - AL_MOD_ENV_RELEASETIME_SOFT, /* 30 - releaseModEnv */ - AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT, /* 31 - keynumToModEnvHold */ - AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT, /* 32 - keynumToModEnvDecay */ - AL_VOLUME_ENV_DELAYTIME_SOFT, /* 33 - delayVolEnv */ - AL_VOLUME_ENV_ATTACKTIME_SOFT, /* 34 - attackVolEnv */ - AL_VOLUME_ENV_HOLDTIME_SOFT, /* 35 - holdVolEnv */ - AL_VOLUME_ENV_DECAYTIME_SOFT, /* 36 - decayVolEnv */ - AL_VOLUME_ENV_SUSTAINVOLUME_SOFT, /* 37 - sustainVolEnv */ - AL_VOLUME_ENV_RELEASETIME_SOFT, /* 38 - releaseVolEnv */ - AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT, /* 39 - keynumToVolEnvHold */ - AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT, /* 40 - keynumToVolEnvDecay */ - 0, /* 41 - */ - 0, /* 42 - */ - AL_KEY_RANGE_SOFT, /* 43 - keyRange */ - AL_VELOCITY_RANGE_SOFT, /* 44 - velRange */ - 0, /* 45 - startloopAddrCoarseOffset */ - 0, /* 46 - keynum */ - 0, /* 47 - velocity */ - AL_ATTENUATION_SOFT, /* 48 - initialAttenuation */ - 0, /* 49 - */ - 0, /* 50 - endloopAddrCoarseOffset */ - AL_TUNING_COARSE_SOFT, /* 51 - corseTune */ - AL_TUNING_FINE_SOFT, /* 52 - fineTune */ - 0, /* 53 - */ - AL_LOOP_MODE_SOFT, /* 54 - sampleModes */ - 0, /* 55 - */ - AL_TUNING_SCALE_SOFT, /* 56 - scaleTuning */ - AL_EXCLUSIVE_CLASS_SOFT, /* 57 - exclusiveClass */ - AL_BASE_KEY_SOFT, /* 58 - overridingRootKey */ - 0, /* 59 - */ - }; - const Generator *gen, *gen_end; - const Modulator *mod, *mod_end; - - mod = VECTOR_ITER_BEGIN(zone->mods); - mod_end = VECTOR_ITER_END(zone->mods); - for(;mod != mod_end;mod++) - { - ALenum src0in = getModSrcInput(mod->mSrcOp&0xFF); - ALenum src0type = getModSrcType(mod->mSrcOp&0x0300); - ALenum src0form = getModSrcForm(mod->mSrcOp&0xFC00); - ALenum src1in = getModSrcInput(mod->mAmtSrcOp&0xFF); - ALenum src1type = getModSrcType(mod->mAmtSrcOp&0x0300); - ALenum src1form = getModSrcForm(mod->mAmtSrcOp&0xFC00); - ALenum trans = getModTransOp(mod->mTransOp); - ALenum dst = (mod->mDstOp < 60) ? Gen2Param[mod->mDstOp] : 0; - if(!dst || dst == AL_KEY_RANGE_SOFT || dst == AL_VELOCITY_RANGE_SOFT || - dst == AL_LOOP_MODE_SOFT || dst == AL_EXCLUSIVE_CLASS_SOFT || - dst == AL_BASE_KEY_SOFT) - ERR("Unhandled modulator destination: %d\n", mod->mDstOp); - else if(src0in != AL_INVALID && src0form != AL_INVALID && src0type != AL_INVALID && - src1in != AL_INVALID && src1form != AL_INVALID && src0type != AL_INVALID && - trans != AL_INVALID) - { - ALsizei idx = (ALsizei)(mod - VECTOR_ITER_BEGIN(zone->mods)); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE0_INPUT_SOFT, src0in); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE0_TYPE_SOFT, src0type); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE0_FORM_SOFT, src0form); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE1_INPUT_SOFT, src1in); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE1_TYPE_SOFT, src1type); - ALfontsound_setModStagei(sound, context, idx, AL_SOURCE1_FORM_SOFT, src1form); - ALfontsound_setModStagei(sound, context, idx, AL_AMOUNT_SOFT, mod->mAmount); - ALfontsound_setModStagei(sound, context, idx, AL_TRANSFORM_OP_SOFT, trans); - ALfontsound_setModStagei(sound, context, idx, AL_DESTINATION_SOFT, dst); - } - } - - gen = VECTOR_ITER_BEGIN(zone->gens); - gen_end = VECTOR_ITER_END(zone->gens); - for(;gen != gen_end;gen++) - { - ALint value = (ALshort)gen->mAmount; - if(gen->mGenerator == 0) - sound->Start += value; - else if(gen->mGenerator == 1) - sound->End += value; - else if(gen->mGenerator == 2) - sound->LoopStart += value; - else if(gen->mGenerator == 3) - sound->LoopEnd += value; - else if(gen->mGenerator == 4) - sound->Start += value<<15; - else if(gen->mGenerator == 12) - sound->End += value<<15; - else if(gen->mGenerator == 45) - sound->LoopStart += value<<15; - else if(gen->mGenerator == 50) - sound->LoopEnd += value<<15; - else if(gen->mGenerator == 43) - { - sound->MinKey = mini((value&0xff), 127); - sound->MaxKey = mini(((value>>8)&0xff), 127); - } - else if(gen->mGenerator == 44) - { - sound->MinVelocity = mini((value&0xff), 127); - sound->MaxVelocity = mini(((value>>8)&0xff), 127); - } - else - { - ALenum param = 0; - if(gen->mGenerator < 60) - param = Gen2Param[gen->mGenerator]; - if(param) - { - if(param == AL_BASE_KEY_SOFT) - { - if(!(value >= 0 && value <= 127)) - { - if(value != -1) - WARN("Invalid overridingRootKey generator value %d\n", value); - continue; - } - } - if(param == AL_FILTER_RESONANCE_SOFT || param == AL_ATTENUATION_SOFT) - value = maxi(0, value); - else if(param == AL_CHORUS_SEND_SOFT || param == AL_REVERB_SEND_SOFT) - value = clampi(value, 0, 1000); - else if(param == AL_LOOP_MODE_SOFT) - value = getLoopMode(value); - ALfontsound_setPropi(sound, context, param, value); - } - else - { - static ALuint warned[65536/32]; - if(!(warned[gen->mGenerator/32]&(1<<(gen->mGenerator&31)))) - { - warned[gen->mGenerator/32] |= 1<<(gen->mGenerator&31); - ERR("Unhandled generator %d\n", gen->mGenerator); - } - } - } - } -} - -static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCcontext *context, ALbuffer *buffer, InstrumentHeader *inst, const PresetHeader *preset, const Soundfont *sfont, const GenModList *pzone) -{ - const Generator *gen, *gen_end; - const Modulator *mod, *mod_end; - const Zone *zone, *zone_end; - GenModList gzone; - ALvoid *temp; - - if((inst+1)->mZoneIdx == inst->mZoneIdx) - ERR("Instrument with no zones!"); - - GenModList_Construct(&gzone); - zone = sfont->ibag + inst->mZoneIdx; - zone_end = sfont->ibag + (inst+1)->mZoneIdx; - if(zone_end-zone > 1) - { - gen = sfont->igen + zone->mGenIdx; - gen_end = sfont->igen + (zone+1)->mGenIdx; - - // If no generators, or last generator is not a sample, this is a global zone - for(;gen != gen_end;gen++) - { - if(gen->mGenerator == 53) - break; - } - - if(gen == gen_end) - { - gen = sfont->igen + zone->mGenIdx; - gen_end = sfont->igen + (zone+1)->mGenIdx; - for(;gen != gen_end;gen++) - GenModList_insertGen(&gzone, gen, AL_FALSE); - - mod = sfont->imod + zone->mModIdx; - mod_end = sfont->imod + (zone+1)->mModIdx; - for(;mod != mod_end;mod++) - GenModList_insertMod(&gzone, mod); - - zone++; - } - } - - temp = realloc(*sounds, (zone_end-zone + *sounds_size)*sizeof((*sounds)[0])); - if(!temp) - { - ERR("Failed reallocating fontsound storage to %d elements (from %d)\n", - (ALsizei)(zone_end-zone) + *sounds_size, *sounds_size); - return; - } - *sounds = temp; - for(;zone != zone_end;zone++) - { - GenModList lzone = GenModList_clone(&gzone); - mod = sfont->imod + zone->mModIdx; - mod_end = sfont->imod + (zone+1)->mModIdx; - for(;mod != mod_end;mod++) - GenModList_insertMod(&lzone, mod); - - gen = sfont->igen + zone->mGenIdx; - gen_end = sfont->igen + (zone+1)->mGenIdx; - for(;gen != gen_end;gen++) - { - if(gen->mGenerator == 53) - { - const SampleHeader *samp; - ALfontsound *sound; - - if(gen->mAmount >= sfont->shdr_size-1) - { - ERR("Generator %ld has invalid sample ID (%d of %d)\n", - (long)(gen-sfont->igen), gen->mAmount, sfont->shdr_size-1); - break; - } - samp = &sfont->shdr[gen->mAmount]; - - gen = VECTOR_ITER_BEGIN(pzone->gens); - gen_end = VECTOR_ITER_END(pzone->gens); - for(;gen != gen_end;gen++) - GenModList_accumGen(&lzone, gen); - - mod = VECTOR_ITER_BEGIN(pzone->mods); - mod_end = VECTOR_ITER_END(pzone->mods); - for(;mod != mod_end;mod++) - GenModList_accumMod(&lzone, mod); - - if(!checkZone(&lzone, preset, inst, samp)) - break; - /* Ignore ROM samples for now. */ - if((samp->mSampleType&0x8000)) - break; - - sound = NewFontsound(context); - (*sounds)[(*sounds_size)++] = sound; - ALfontsound_setPropi(sound, context, AL_BUFFER, buffer->id); - ALfontsound_setPropi(sound, context, AL_SAMPLE_START_SOFT, samp->mStart); - ALfontsound_setPropi(sound, context, AL_SAMPLE_END_SOFT, samp->mEnd); - ALfontsound_setPropi(sound, context, AL_SAMPLE_LOOP_START_SOFT, samp->mStartloop); - ALfontsound_setPropi(sound, context, AL_SAMPLE_LOOP_END_SOFT, samp->mEndloop); - ALfontsound_setPropi(sound, context, AL_SAMPLE_RATE_SOFT, samp->mSampleRate); - ALfontsound_setPropi(sound, context, AL_BASE_KEY_SOFT, (samp->mOriginalKey <= 127) ? samp->mOriginalKey : 60); - ALfontsound_setPropi(sound, context, AL_KEY_CORRECTION_SOFT, samp->mCorrection); - ALfontsound_setPropi(sound, context, AL_SAMPLE_TYPE_SOFT, getSampleType(samp->mSampleType&0x7fff)); - fillZone(sound, context, &lzone); - - break; - } - GenModList_insertGen(&lzone, gen, AL_FALSE); - } - - GenModList_Destruct(&lzone); - } - - GenModList_Destruct(&gzone); -} - -static size_t printStringChunk(Reader *stream, const RiffHdr *chnk, const char *title) -{ - size_t len = 0; - if(chnk->mSize == 0 || (chnk->mSize&1)) - ERR("Invalid "FOURCCFMT" size: %d\n", FOURCCARGS(chnk->mCode), chnk->mSize); - else - { - char *str = calloc(1, chnk->mSize+1); - len = Reader_read(stream, str, chnk->mSize); - - TRACE("%s: %s\n", title, str); - free(str); - } - return len; -} - -ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context) -{ - ALsfpreset **presets = NULL; - ALsizei presets_size = 0; - ALbuffer *buffer = NULL; - ALuint ltype; - Soundfont sfont; - RiffHdr riff; - RiffHdr list; - ALsizei i; - - Soundfont_Construct(&sfont); - - RiffHdr_read(&riff, stream); - if(riff.mCode != FOURCC('R','I','F','F')) - ERROR_GOTO(error, "Invalid Format, expected RIFF got '"FOURCCFMT"'\n", FOURCCARGS(riff.mCode)); - if((ltype=read_le32(stream)) != FOURCC('s','f','b','k')) - ERROR_GOTO(error, "Invalid Format, expected sfbk got '"FOURCCFMT"'\n", FOURCCARGS(ltype)); - - if(READERR(stream) != 0) - ERROR_GOTO(error, "Error reading file header\n"); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('L','I','S','T')) - ERROR_GOTO(error, "Invalid Format, expected LIST (INFO) got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((ltype=read_le32(stream)) != FOURCC('I','N','F','O')) - ERROR_GOTO(error, "Invalid Format, expected INFO got '"FOURCCFMT"'\n", FOURCCARGS(ltype)); - list.mSize -= 4; - while(list.mSize > 0 && !READERR(stream)) - { - RiffHdr chnk; - - if(list.mSize < 8) - { - WARN("Unexpected end of INFO list (%u extra bytes)\n", list.mSize); - skip(stream, list.mSize); - list.mSize = 0; - break; - } - - RiffHdr_read(&chnk, stream); - list.mSize -= 8; - if(list.mSize < chnk.mSize) - { - WARN("INFO sub-chunk '"FOURCCFMT"' has %u bytes, but only %u bytes remain\n", - FOURCCARGS(chnk.mCode), chnk.mSize, list.mSize); - skip(stream, list.mSize); - list.mSize = 0; - break; - } - list.mSize -= chnk.mSize; - - if(chnk.mCode == FOURCC('i','f','i','l')) - { - if(chnk.mSize != 4) - ERR("Invalid ifil chunk size: %d\n", chnk.mSize); - else - { - ALushort major = read_le16(stream); - ALushort minor = read_le16(stream); - chnk.mSize -= 4; - - if(major != 2) - ERROR_GOTO(error, "Unsupported SF2 format version: %d.%02d\n", major, minor); - TRACE("SF2 format version: %d.%02d\n", major, minor); - - sfont.ifil = (major<<16) | minor; - } - } - else if(chnk.mCode == FOURCC('i','r','o','m')) - { - if(chnk.mSize == 0 || (chnk.mSize&1)) - ERR("Invalid irom size: %d\n", chnk.mSize); - else - { - free(sfont.irom); - sfont.irom = calloc(1, chnk.mSize+1); - chnk.mSize -= Reader_read(stream, sfont.irom, chnk.mSize); - - TRACE("SF2 ROM ID: %s\n", sfont.irom); - } - } - else - { - static const struct { - ALuint code; - char title[16]; - } listinfos[] = { - { FOURCC('i','s','n','g'), "Engine ID" }, - { FOURCC('I','N','A','M'), "Name" }, - { FOURCC('I','C','R','D'), "Creation Date" }, - { FOURCC('I','E','N','G'), "Creator" }, - { FOURCC('I','P','R','D'), "Product ID" }, - { FOURCC('I','C','O','P'), "Copyright" }, - { FOURCC('I','C','M','T'), "Comment" }, - { FOURCC('I','S','F','T'), "Created With" }, - { 0, "" }, - }; - - for(i = 0;listinfos[i].code;i++) - { - if(listinfos[i].code == chnk.mCode) - { - chnk.mSize -= printStringChunk(stream, &chnk, listinfos[i].title); - break; - } - } - if(!listinfos[i].code) - TRACE("Skipping INFO sub-chunk '"FOURCCFMT"' (%u bytes)\n", FOURCCARGS(chnk.mCode), chnk.mSize); - } - skip(stream, chnk.mSize); - } - - if(READERR(stream) != 0) - ERROR_GOTO(error, "Error reading INFO chunk\n"); - if(sfont.ifil == 0) - ERROR_GOTO(error, "Missing ifil sub-chunk\n"); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('L','I','S','T')) - ERROR_GOTO(error, "Invalid Format, expected LIST (sdta) got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((ltype=read_le32(stream)) != FOURCC('s','d','t','a')) - ERROR_GOTO(error, "Invalid Format, expected sdta got '"FOURCCFMT"'\n", FOURCCARGS(ltype)); - list.mSize -= 4; - { - ALbyte *ptr; - RiffHdr smpl; - ALenum err; - - RiffHdr_read(&smpl, stream); - if(smpl.mCode != FOURCC('s','m','p','l')) - ERROR_GOTO(error, "Invalid Format, expected smpl got '"FOURCCFMT"'\n", FOURCCARGS(smpl.mCode)); - list.mSize -= 8; - - if(smpl.mSize > list.mSize) - ERROR_GOTO(error, "Invalid Format, sample chunk size mismatch\n"); - list.mSize -= smpl.mSize; - - buffer = NewBuffer(context); - if(!buffer) - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, error); - /* Sample rate is unimportant, the individual fontsounds will specify it. */ - if((err=LoadData(buffer, 22050, AL_MONO16_SOFT, smpl.mSize/2, UserFmtMono, UserFmtShort, NULL, 1, AL_FALSE)) != AL_NO_ERROR) - SET_ERROR_AND_GOTO(context, err, error); - - ptr = buffer->data; - if(IS_LITTLE_ENDIAN) - smpl.mSize -= Reader_read(stream, ptr, smpl.mSize); - else - { - ALuint total = 0; - while(total < smpl.mSize && !READERR(stream)) - { - ALbyte buf[4096]; - ALuint todo = minu(smpl.mSize-total, sizeof(buf)); - ALuint i; - - smpl.mSize -= Reader_read(stream, buf, todo); - for(i = 0;i < todo;i++) - ptr[total+i] = buf[i^1]; - - total += todo; - } - } - - skip(stream, list.mSize); - } - - if(READERR(stream) != 0) - ERROR_GOTO(error, "Error reading sdta chunk\n"); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('L','I','S','T')) - ERROR_GOTO(error, "Invalid Format, expected LIST (pdta) got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((ltype=read_le32(stream)) != FOURCC('p','d','t','a')) - ERROR_GOTO(error, "Invalid Format, expected pdta got '"FOURCCFMT"'\n", FOURCCARGS(ltype)); - - // - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('p','h','d','r')) - ERROR_GOTO(error, "Invalid Format, expected phdr got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%38) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad phdr size: %u\n", list.mSize); - sfont.phdr_size = list.mSize/38; - sfont.phdr = calloc(sfont.phdr_size, sizeof(sfont.phdr[0])); - for(i = 0;i < sfont.phdr_size;i++) - PresetHeader_read(&sfont.phdr[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('p','b','a','g')) - ERROR_GOTO(error, "Invalid Format, expected pbag got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%4) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad pbag size: %u\n", list.mSize); - sfont.pbag_size = list.mSize/4; - sfont.pbag = calloc(sfont.pbag_size, sizeof(sfont.pbag[0])); - for(i = 0;i < sfont.pbag_size;i++) - Zone_read(&sfont.pbag[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('p','m','o','d')) - ERROR_GOTO(error, "Invalid Format, expected pmod got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%10) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad pmod size: %u\n", list.mSize); - sfont.pmod_size = list.mSize/10; - sfont.pmod = calloc(sfont.pmod_size, sizeof(sfont.pmod[0])); - for(i = 0;i < sfont.pmod_size;i++) - Modulator_read(&sfont.pmod[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('p','g','e','n')) - ERROR_GOTO(error, "Invalid Format, expected pgen got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%4) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad pgen size: %u\n", list.mSize); - sfont.pgen_size = list.mSize/4; - sfont.pgen = calloc(sfont.pgen_size, sizeof(sfont.pgen[0])); - for(i = 0;i < sfont.pgen_size;i++) - Generator_read(&sfont.pgen[i], stream); - - // - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('i','n','s','t')) - ERROR_GOTO(error, "Invalid Format, expected inst got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%22) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad inst size: %u\n", list.mSize); - sfont.inst_size = list.mSize/22; - sfont.inst = calloc(sfont.inst_size, sizeof(sfont.inst[0])); - for(i = 0;i < sfont.inst_size;i++) - InstrumentHeader_read(&sfont.inst[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('i','b','a','g')) - ERROR_GOTO(error, "Invalid Format, expected ibag got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%4) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad ibag size: %u\n", list.mSize); - sfont.ibag_size = list.mSize/4; - sfont.ibag = calloc(sfont.ibag_size, sizeof(sfont.ibag[0])); - for(i = 0;i < sfont.ibag_size;i++) - Zone_read(&sfont.ibag[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('i','m','o','d')) - ERROR_GOTO(error, "Invalid Format, expected imod got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%10) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad imod size: %u\n", list.mSize); - sfont.imod_size = list.mSize/10; - sfont.imod = calloc(sfont.imod_size, sizeof(sfont.imod[0])); - for(i = 0;i < sfont.imod_size;i++) - Modulator_read(&sfont.imod[i], stream); - - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('i','g','e','n')) - ERROR_GOTO(error, "Invalid Format, expected igen got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%4) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad igen size: %u\n", list.mSize); - sfont.igen_size = list.mSize/4; - sfont.igen = calloc(sfont.igen_size, sizeof(sfont.igen[0])); - for(i = 0;i < sfont.igen_size;i++) - Generator_read(&sfont.igen[i], stream); - - // - RiffHdr_read(&list, stream); - if(list.mCode != FOURCC('s','h','d','r')) - ERROR_GOTO(error, "Invalid Format, expected shdr got '"FOURCCFMT"'\n", FOURCCARGS(list.mCode)); - if((list.mSize%46) != 0 || list.mSize == 0) - ERROR_GOTO(error, "Invalid Format, bad shdr size: %u\n", list.mSize); - sfont.shdr_size = list.mSize/46; - sfont.shdr = calloc(sfont.shdr_size, sizeof(sfont.shdr[0])); - for(i = 0;i < sfont.shdr_size;i++) - SampleHeader_read(&sfont.shdr[i], stream); - - if(READERR(stream) != 0) - ERROR_GOTO(error, "Error reading pdta chunk\n"); - - if(!ensureFontSanity(&sfont)) - goto error; - - presets = calloc(1, (soundfont->NumPresets+sfont.phdr_size-1)*sizeof(presets[0])); - if(!presets) - ERROR_GOTO(error, "Error allocating presets\n"); - memcpy(presets, soundfont->Presets, soundfont->NumPresets*sizeof(presets[0])); - presets_size = soundfont->NumPresets; - - for(i = 0;i < sfont.phdr_size-1;i++) - { - const Generator *gen, *gen_end; - const Modulator *mod, *mod_end; - const Zone *zone, *zone_end; - ALfontsound **sounds = NULL; - ALsizei sounds_size = 0; - GenModList gzone; - - if(sfont.phdr[i+1].mZoneIdx == sfont.phdr[i].mZoneIdx) - continue; - - GenModList_Construct(&gzone); - zone = sfont.pbag + sfont.phdr[i].mZoneIdx; - zone_end = sfont.pbag + sfont.phdr[i+1].mZoneIdx; - if(zone_end-zone > 1) - { - gen = sfont.pgen + zone->mGenIdx; - gen_end = sfont.pgen + (zone+1)->mGenIdx; - - // If no generators, or last generator is not an instrument, this is a global zone - for(;gen != gen_end;gen++) - { - if(gen->mGenerator == 41) - break; - } - - if(gen == gen_end) - { - gen = sfont.pgen + zone->mGenIdx; - gen_end = sfont.pgen + (zone+1)->mGenIdx; - for(;gen != gen_end;gen++) - GenModList_insertGen(&gzone, gen, AL_TRUE); - - mod = sfont.pmod + zone->mModIdx; - mod_end = sfont.pmod + (zone+1)->mModIdx; - for(;mod != mod_end;mod++) - GenModList_insertMod(&gzone, mod); - - zone++; - } - } - - for(;zone != zone_end;zone++) - { - GenModList lzone = GenModList_clone(&gzone); - - mod = sfont.pmod + zone->mModIdx; - mod_end = sfont.pmod + (zone+1)->mModIdx; - for(;mod != mod_end;mod++) - GenModList_insertMod(&lzone, mod); - - gen = sfont.pgen + zone->mGenIdx; - gen_end = sfont.pgen + (zone+1)->mGenIdx; - for(;gen != gen_end;gen++) - { - if(gen->mGenerator == 41) - { - if(gen->mAmount >= sfont.inst_size-1) - ERR("Generator %ld has invalid instrument ID (%d of %d)\n", - (long)(gen-sfont.pgen), gen->mAmount, sfont.inst_size-1); - else - processInstrument( - &sounds, &sounds_size, context, buffer, &sfont.inst[gen->mAmount], - &sfont.phdr[i], &sfont, &lzone - ); - break; - } - GenModList_insertGen(&lzone, gen, AL_TRUE); - } - GenModList_Destruct(&lzone); - } - - if(sounds_size > 0) - { - ALsizei j; - - presets[presets_size] = NewPreset(context); - presets[presets_size]->Preset = sfont.phdr[i].mPreset; - presets[presets_size]->Bank = sfont.phdr[i].mBank; - - for(j = 0;j < sounds_size;j++) - IncrementRef(&sounds[j]->ref); - sounds = ExchangePtr((XchgPtr*)&presets[presets_size]->Sounds, sounds); - ExchangeInt(&presets[presets_size]->NumSounds, sounds_size); - presets_size++; - } - free(sounds); - - GenModList_Destruct(&gzone); - } - - for(i = soundfont->NumPresets;i < presets_size;i++) - IncrementRef(&presets[i]->ref); - presets = ExchangePtr((XchgPtr*)&soundfont->Presets, presets); - ExchangeInt(&soundfont->NumPresets, presets_size); - - free(presets); - - Soundfont_Destruct(&sfont); - /* If the buffer ends up unused, delete it. */ - if(ReadRef(&buffer->ref) == 0) - { - TRACE("Deleting unused buffer...\n"); - DeleteBuffer(context->Device, buffer); - } - - return AL_TRUE; - -error: - if(presets) - { - ALCdevice *device = context->Device; - for(i = soundfont->NumPresets;i < presets_size;i++) - DeletePreset(device, presets[i]); - free(presets); - } - - Soundfont_Destruct(&sfont); - if(buffer) - DeleteBuffer(context->Device, buffer); - - return AL_FALSE; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/midi/soft.c b/love/src/jni/openal-soft-1.17.0/Alc/midi/soft.c deleted file mode 100644 index 6566b411..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/midi/soft.c +++ /dev/null @@ -1,140 +0,0 @@ - -#include "config.h" - -#include -#include -#include -#include - -#include "alMain.h" -#include "alError.h" -#include "evtqueue.h" -#include "alu.h" - -#include "midi/base.h" - - -typedef struct SSynth { - DERIVE_FROM_TYPE(MidiSynth); -} SSynth; - -static void SSynth_mixSamples(SSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); - -static void SSynth_Construct(SSynth *self, ALCdevice *device); -static void SSynth_Destruct(SSynth *self); -static DECLARE_FORWARD3(SSynth, MidiSynth, ALenum, selectSoundfonts, ALCcontext*, ALsizei, const ALuint*) -static DECLARE_FORWARD1(SSynth, MidiSynth, void, setGain, ALfloat) -static DECLARE_FORWARD(SSynth, MidiSynth, void, stop) -static DECLARE_FORWARD(SSynth, MidiSynth, void, reset) -static void SSynth_update(SSynth *self, ALCdevice *device); -static void SSynth_process(SSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]); -DECLARE_DEFAULT_ALLOCATORS(SSynth) -DEFINE_MIDISYNTH_VTABLE(SSynth); - - -static void SSynth_Construct(SSynth *self, ALCdevice *device) -{ - MidiSynth_Construct(STATIC_CAST(MidiSynth, self), device); - SET_VTABLE2(SSynth, MidiSynth, self); -} - -static void SSynth_Destruct(SSynth* UNUSED(self)) -{ -} - - -static void SSynth_update(SSynth* UNUSED(self), ALCdevice* UNUSED(device)) -{ -} - - -static void SSynth_mixSamples(SSynth* UNUSED(self), ALuint UNUSED(SamplesToDo), ALfloatBUFFERSIZE *restrict UNUSED(DryBuffer)) -{ -} - - -static void SSynth_processQueue(SSynth *self, ALuint64 time) -{ - EvtQueue *queue = &STATIC_CAST(MidiSynth, self)->EventQueue; - - while(queue->pos < queue->size && queue->events[queue->pos].time <= time) - queue->pos++; -} - -static void SSynth_process(SSynth *self, ALuint SamplesToDo, ALfloat (*restrict DryBuffer)[BUFFERSIZE]) -{ - MidiSynth *synth = STATIC_CAST(MidiSynth, self); - ALenum state = synth->State; - ALuint64 curtime; - ALuint total = 0; - - if(state == AL_INITIAL) - return; - if(state != AL_PLAYING) - { - SSynth_mixSamples(self, SamplesToDo, DryBuffer); - return; - } - - curtime = MidiSynth_getTime(synth); - while(total < SamplesToDo) - { - ALuint64 time, diff; - ALint tonext; - - time = MidiSynth_getNextEvtTime(synth); - diff = maxu64(time, curtime) - curtime; - if(diff >= MIDI_CLOCK_RES || time == UINT64_MAX) - { - /* If there's no pending event, or if it's more than 1 second - * away, do as many samples as we can. */ - tonext = INT_MAX; - } - else - { - /* Figure out how many samples until the next event. */ - tonext = (ALint)((diff*synth->SampleRate + (MIDI_CLOCK_RES-1)) / MIDI_CLOCK_RES); - tonext -= total; - /* For efficiency reasons, try to mix a multiple of 64 samples - * (~1ms @ 44.1khz) before processing the next event. */ - tonext = (tonext+63) & ~63; - } - - if(tonext > 0) - { - ALuint todo = mini(tonext, SamplesToDo-total); - SSynth_mixSamples(self, todo, DryBuffer); - total += todo; - tonext -= todo; - } - if(total < SamplesToDo && tonext <= 0) - SSynth_processQueue(self, time); - } - - synth->SamplesDone += SamplesToDo; - synth->ClockBase += (synth->SamplesDone/synth->SampleRate) * MIDI_CLOCK_RES; - synth->SamplesDone %= synth->SampleRate; -} - - -MidiSynth *SSynth_create(ALCdevice *device) -{ - SSynth *synth; - - /* This option is temporary. Once this synth is in a more usable state, a - * more generic selector should be used. */ - if(!GetConfigValueBool("midi", "internal-synth", 0)) - { - TRACE("Not using internal MIDI synth\n"); - return NULL; - } - - synth = SSynth_New(sizeof(*synth)); - if(!synth) - { - ERR("Failed to allocate SSynth\n"); - return NULL; - } - SSynth_Construct(synth, device); - return STATIC_CAST(MidiSynth, synth); -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer.c deleted file mode 100644 index f3b8f599..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer.c +++ /dev/null @@ -1,510 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" -#include "alSource.h" -#include "alBuffer.h" -#include "alListener.h" -#include "alAuxEffectSlot.h" -#include "alu.h" - -#include "mixer_defs.h" - - -extern inline void InitiatePositionArrays(ALuint frac, ALuint increment, ALuint *frac_arr, ALuint *pos_arr, ALuint size); - - -static inline HrtfMixerFunc SelectHrtfMixer(void) -{ -#ifdef HAVE_SSE - if((CPUCapFlags&CPU_CAP_SSE)) - return MixHrtf_SSE; -#endif -#ifdef HAVE_NEON - if((CPUCapFlags&CPU_CAP_NEON)) - return MixHrtf_Neon; -#endif - - return MixHrtf_C; -} - -static inline MixerFunc SelectMixer(void) -{ -#ifdef HAVE_SSE - if((CPUCapFlags&CPU_CAP_SSE)) - return Mix_SSE; -#endif -#ifdef HAVE_NEON - if((CPUCapFlags&CPU_CAP_NEON)) - return Mix_Neon; -#endif - - return Mix_C; -} - -static inline ResamplerFunc SelectResampler(enum Resampler Resampler, ALuint increment) -{ - if(increment == FRACTIONONE) - return Resample_copy32_C; - switch(Resampler) - { - case PointResampler: - return Resample_point32_C; - case LinearResampler: -#ifdef HAVE_SSE4_1 - if((CPUCapFlags&CPU_CAP_SSE4_1)) - return Resample_lerp32_SSE41; -#endif -#ifdef HAVE_SSE2 - if((CPUCapFlags&CPU_CAP_SSE2)) - return Resample_lerp32_SSE2; -#endif - return Resample_lerp32_C; - case CubicResampler: - return Resample_cubic32_C; - case ResamplerMax: - /* Shouldn't happen */ - break; - } - - return Resample_point32_C; -} - - -static inline ALfloat Sample_ALbyte(ALbyte val) -{ return val * (1.0f/127.0f); } - -static inline ALfloat Sample_ALshort(ALshort val) -{ return val * (1.0f/32767.0f); } - -static inline ALfloat Sample_ALfloat(ALfloat val) -{ return val; } - -#define DECL_TEMPLATE(T) \ -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*srcstep]); \ -} - -DECL_TEMPLATE(ALbyte) -DECL_TEMPLATE(ALshort) -DECL_TEMPLATE(ALfloat) - -#undef DECL_TEMPLATE - -static void LoadSamples(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples) -{ - switch(srctype) - { - case FmtByte: - Load_ALbyte(dst, src, srcstep, samples); - break; - case FmtShort: - Load_ALshort(dst, src, srcstep, samples); - break; - case FmtFloat: - Load_ALfloat(dst, src, srcstep, samples); - break; - } -} - -static void SilenceSamples(ALfloat *dst, ALuint samples) -{ - ALuint i; - for(i = 0;i < samples;i++) - dst[i] = 0.0f; -} - - -static const ALfloat *DoFilters(ALfilterState *lpfilter, ALfilterState *hpfilter, - ALfloat *restrict dst, const ALfloat *restrict src, - ALuint numsamples, enum ActiveFilters type) -{ - ALuint i; - switch(type) - { - case AF_None: - break; - - case AF_LowPass: - ALfilterState_process(lpfilter, dst, src, numsamples); - return dst; - case AF_HighPass: - ALfilterState_process(hpfilter, dst, src, numsamples); - return dst; - - case AF_BandPass: - for(i = 0;i < numsamples;) - { - ALfloat temp[64]; - ALuint todo = minu(64, numsamples-i); - - ALfilterState_process(lpfilter, temp, src+i, todo); - ALfilterState_process(hpfilter, dst+i, temp, todo); - i += todo; - } - return dst; - } - return src; -} - - -ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo) -{ - MixerFunc Mix; - HrtfMixerFunc HrtfMix; - ResamplerFunc Resample; - ALsource *Source = src->Source; - ALbufferlistitem *BufferListItem; - ALuint DataPosInt, DataPosFrac; - ALboolean Looping; - ALuint increment; - enum Resampler Resampler; - ALenum State; - ALuint OutPos; - ALuint NumChannels; - ALuint SampleSize; - ALint64 DataSize64; - ALuint chan, j; - - /* Get source info */ - State = Source->state; - BufferListItem = ATOMIC_LOAD(&Source->current_buffer); - DataPosInt = Source->position; - DataPosFrac = Source->position_fraction; - Looping = Source->Looping; - increment = src->Step; - Resampler = (increment==FRACTIONONE) ? PointResampler : Source->Resampler; - NumChannels = Source->NumChannels; - SampleSize = Source->SampleSize; - - Mix = SelectMixer(); - HrtfMix = SelectHrtfMixer(); - Resample = SelectResampler(Resampler, increment); - - OutPos = 0; - do { - const ALuint BufferPrePadding = ResamplerPrePadding[Resampler]; - const ALuint BufferPadding = ResamplerPadding[Resampler]; - ALuint SrcBufferSize, DstBufferSize; - - /* Figure out how many buffer samples will be needed */ - DataSize64 = SamplesToDo-OutPos; - DataSize64 *= increment; - DataSize64 += DataPosFrac+FRACTIONMASK; - DataSize64 >>= FRACTIONBITS; - DataSize64 += BufferPadding+BufferPrePadding; - - SrcBufferSize = (ALuint)mini64(DataSize64, BUFFERSIZE); - - /* Figure out how many samples we can actually mix from this. */ - DataSize64 = SrcBufferSize; - DataSize64 -= BufferPadding+BufferPrePadding; - DataSize64 <<= FRACTIONBITS; - DataSize64 -= DataPosFrac; - - DstBufferSize = (ALuint)((DataSize64+(increment-1)) / increment); - DstBufferSize = minu(DstBufferSize, (SamplesToDo-OutPos)); - - /* 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++) - { - const ALfloat *ResampledData; - ALfloat *SrcData = Device->SourceData; - ALuint SrcDataSize = 0; - - if(Source->SourceType == AL_STATIC) - { - const ALbuffer *ALBuffer = BufferListItem->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); - - SilenceSamples(&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); - - LoadSamples(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize], - NumChannels, ALBuffer->FmtType, DataSize); - SrcDataSize += DataSize; - - SilenceSamples(&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); - - SilenceSamples(&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); - - LoadSamples(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize], - NumChannels, ALBuffer->FmtType, DataSize); - SrcDataSize += DataSize; - - DataSize = LoopEnd-LoopStart; - while(SrcBufferSize > SrcDataSize) - { - DataSize = minu(SrcBufferSize - SrcDataSize, DataSize); - - LoadSamples(&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) - { - ALbufferlistitem *prev; - if((prev=tmpiter->prev) != NULL) - tmpiter = prev; - else if(Looping) - { - while(tmpiter->next) - tmpiter = tmpiter->next; - } - else - { - ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos); - - SilenceSamples(&SrcData[SrcDataSize], DataSize); - SrcDataSize += DataSize; - - pos = 0; - break; - } - - 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); - LoadSamples(&SrcData[SrcDataSize], Data, NumChannels, - ALBuffer->FmtType, DataSize); - SrcDataSize += DataSize; - } - } - tmpiter = tmpiter->next; - if(!tmpiter && Looping) - tmpiter = ATOMIC_LOAD(&Source->queue); - else if(!tmpiter) - { - SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize); - SrcDataSize += SrcBufferSize - SrcDataSize; - } - } - } - - /* Now resample, then filter and mix to the appropriate outputs. */ - ResampledData = Resample( - &SrcData[BufferPrePadding], DataPosFrac, increment, - Device->ResampledData, DstBufferSize - ); - { - DirectParams *parms = &src->Direct; - const ALfloat *samples; - - samples = DoFilters( - &parms->Filters[chan].LowPass, &parms->Filters[chan].HighPass, - Device->FilteredData, ResampledData, DstBufferSize, - parms->Filters[chan].ActiveType - ); - if(!src->IsHrtf) - Mix(samples, MaxChannels, parms->OutBuffer, parms->Mix.Gains[chan], - parms->Counter, OutPos, DstBufferSize); - else - HrtfMix(parms->OutBuffer, samples, parms->Counter, src->Offset, - OutPos, parms->Mix.Hrtf.IrSize, &parms->Mix.Hrtf.Params[chan], - &parms->Mix.Hrtf.State[chan], DstBufferSize); - } - - for(j = 0;j < Device->NumAuxSends;j++) - { - SendParams *parms = &src->Send[j]; - const ALfloat *samples; - - if(!parms->OutBuffer) - continue; - - samples = DoFilters( - &parms->Filters[chan].LowPass, &parms->Filters[chan].HighPass, - Device->FilteredData, ResampledData, DstBufferSize, - parms->Filters[chan].ActiveType - ); - Mix(samples, 1, parms->OutBuffer, &parms->Gain, - parms->Counter, OutPos, DstBufferSize); - } - } - /* Update positions */ - DataPosFrac += increment*DstBufferSize; - DataPosInt += DataPosFrac>>FRACTIONBITS; - DataPosFrac &= FRACTIONMASK; - - OutPos += DstBufferSize; - src->Offset += DstBufferSize; - src->Direct.Counter = maxu(src->Direct.Counter, DstBufferSize) - DstBufferSize; - for(j = 0;j < Device->NumAuxSends;j++) - src->Send[j].Counter = maxu(src->Send[j].Counter, DstBufferSize) - DstBufferSize; - - /* Handle looping sources */ - while(1) - { - const ALbuffer *ALBuffer; - ALuint DataSize = 0; - ALuint LoopStart = 0; - ALuint LoopEnd = 0; - - if((ALBuffer=BufferListItem->buffer) != NULL) - { - DataSize = ALBuffer->SampleLen; - LoopStart = ALBuffer->LoopStart; - LoopEnd = ALBuffer->LoopEnd; - if(LoopEnd > DataPosInt) - break; - } - - if(Looping && Source->SourceType == AL_STATIC) - { - assert(LoopEnd > LoopStart); - DataPosInt = ((DataPosInt-LoopStart)%(LoopEnd-LoopStart)) + LoopStart; - break; - } - - if(DataSize > DataPosInt) - break; - - if(!(BufferListItem=BufferListItem->next)) - { - if(Looping) - BufferListItem = ATOMIC_LOAD(&Source->queue); - else - { - State = AL_STOPPED; - BufferListItem = NULL; - DataPosInt = 0; - DataPosFrac = 0; - break; - } - } - - DataPosInt -= DataSize; - } - } while(State == AL_PLAYING && OutPos < SamplesToDo); - - /* Update source info */ - Source->state = State; - ATOMIC_STORE(&Source->current_buffer, BufferListItem); - Source->position = DataPosInt; - Source->position_fraction = DataPosFrac; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_c.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer_c.c deleted file mode 100644 index f3a229e5..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_c.c +++ /dev/null @@ -1,126 +0,0 @@ -#include "config.h" - -#include - -#include "alMain.h" -#include "alu.h" -#include "alSource.h" -#include "alAuxEffectSlot.h" - - -static inline ALfloat point32(const ALfloat *vals, ALuint UNUSED(frac)) -{ return vals[0]; } -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)); } - -const ALfloat *Resample_copy32_C(const ALfloat *src, ALuint UNUSED(frac), - ALuint increment, ALfloat *restrict dst, ALuint numsamples) -{ - assert(increment==FRACTIONONE); -#if defined(HAVE_SSE) || defined(HAVE_NEON) - /* Avoid copying the source data if it's aligned like the destination. */ - if((((intptr_t)src)&15) == (((intptr_t)dst)&15)) - return src; -#endif - memcpy(dst, src, numsamples*sizeof(ALfloat)); - return dst; -} - -#define DECL_TEMPLATE(Sampler) \ -const ALfloat *Resample_##Sampler##_C(const ALfloat *src, ALuint frac, \ - ALuint increment, ALfloat *restrict dst, ALuint numsamples) \ -{ \ - ALuint i; \ - for(i = 0;i < numsamples;i++) \ - { \ - dst[i] = Sampler(src, frac); \ - \ - frac += increment; \ - src += frac>>FRACTIONBITS; \ - frac &= FRACTIONMASK; \ - } \ - return dst; \ -} - -DECL_TEMPLATE(point32) -DECL_TEMPLATE(lerp32) -DECL_TEMPLATE(cubic32) - -#undef DECL_TEMPLATE - - -void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *src, ALuint numsamples) -{ - ALuint i; - for(i = 0;i < numsamples;i++) - *(dst++) = ALfilterState_processSingle(filter, *(src++)); -} - - -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 Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) -{ - ALfloat gain, step; - ALuint c; - - for(c = 0;c < OutChans;c++) - { - ALuint pos = 0; - gain = Gains[c].Current; - step = Gains[c].Step; - if(step != 1.0f && Counter > 0) - { - for(;pos < BufferSize && pos < Counter;pos++) - { - OutBuffer[c][OutPos+pos] += data[pos]*gain; - gain *= step; - } - if(pos == Counter) - gain = Gains[c].Target; - Gains[c].Current = gain; - } - - if(!(gain > GAIN_SILENCE_THRESHOLD)) - continue; - for(;pos < BufferSize;pos++) - OutBuffer[c][OutPos+pos] += data[pos]*gain; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_defs.h b/love/src/jni/openal-soft-1.17.0/Alc/mixer_defs.h deleted file mode 100644 index c1500ed2..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_defs.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef MIXER_DEFS_H -#define MIXER_DEFS_H - -#include "AL/alc.h" -#include "AL/al.h" -#include "alMain.h" -#include "alu.h" - -struct MixGains; - -struct HrtfParams; -struct HrtfState; - -/* C resamplers */ -const ALfloat *Resample_copy32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); -const ALfloat *Resample_point32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); -const ALfloat *Resample_lerp32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); -const ALfloat *Resample_cubic32_C(const ALfloat *src, ALuint frac, ALuint increment, ALfloat *restrict dst, ALuint dstlen); - - -/* C mixers */ -void MixHrtf_C(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); -void Mix_C(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); - -/* SSE mixers */ -void MixHrtf_SSE(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); -void Mix_SSE(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); - -/* SSE resamplers */ -inline void InitiatePositionArrays(ALuint frac, ALuint increment, ALuint *frac_arr, ALuint *pos_arr, ALuint size) -{ - ALuint i; - - pos_arr[0] = 0; - frac_arr[0] = frac; - for(i = 1;i < size;i++) - { - ALuint frac_tmp = frac_arr[i-1] + increment; - pos_arr[i] = pos_arr[i-1] + (frac_tmp>>FRACTIONBITS); - frac_arr[i] = frac_tmp&FRACTIONMASK; - } -} - -const ALfloat *Resample_lerp32_SSE2(const ALfloat *src, ALuint frac, ALuint increment, - ALfloat *restrict dst, ALuint numsamples); -const ALfloat *Resample_lerp32_SSE41(const ALfloat *src, ALuint frac, ALuint increment, - ALfloat *restrict dst, ALuint numsamples); - -/* Neon mixers */ -void MixHrtf_Neon(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const struct HrtfParams *hrtfparams, struct HrtfState *hrtfstate, - ALuint BufferSize); -void Mix_Neon(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - struct MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize); - -#endif /* MIXER_DEFS_H */ diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_inc.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer_inc.c deleted file mode 100644 index ab6f32c5..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_inc.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "config.h" - -#include "alMain.h" -#include "alSource.h" - -#include "hrtf.h" -#include "mixer_defs.h" -#include "align.h" - - -#define REAL_MERGE(a,b) a##b -#define MERGE(a,b) REAL_MERGE(a,b) - -#define MixHrtf MERGE(MixHrtf_,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 MixHrtf(ALfloat (*restrict OutBuffer)[BUFFERSIZE], const ALfloat *data, - ALuint Counter, ALuint Offset, ALuint OutPos, const ALuint IrSize, - const HrtfParams *hrtfparams, HrtfState *hrtfstate, ALuint BufferSize) -{ - alignas(16) ALfloat Coeffs[HRIR_LENGTH][2]; - ALuint Delay[2]; - ALfloat left, right; - ALuint pos; - ALuint c; - - for(c = 0;c < IrSize;c++) - { - Coeffs[c][0] = hrtfparams->Coeffs[c][0] - (hrtfparams->CoeffStep[c][0]*Counter); - Coeffs[c][1] = hrtfparams->Coeffs[c][1] - (hrtfparams->CoeffStep[c][1]*Counter); - } - Delay[0] = hrtfparams->Delay[0] - (hrtfparams->DelayStep[0]*Counter); - Delay[1] = hrtfparams->Delay[1] - (hrtfparams->DelayStep[1]*Counter); - - for(pos = 0;pos < BufferSize && pos < Counter;pos++) - { - hrtfstate->History[Offset&SRC_HISTORY_MASK] = data[pos]; - left = lerp(hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[0]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], - (Delay[0]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - right = lerp(hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS))&SRC_HISTORY_MASK], - hrtfstate->History[(Offset-(Delay[1]>>HRTFDELAY_BITS)-1)&SRC_HISTORY_MASK], - (Delay[1]&HRTFDELAY_MASK)*(1.0f/HRTFDELAY_FRACONE)); - - Delay[0] += hrtfparams->DelayStep[0]; - Delay[1] += hrtfparams->DelayStep[1]; - - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; - Offset++; - - ApplyCoeffsStep(Offset, hrtfstate->Values, IrSize, Coeffs, hrtfparams->CoeffStep, left, right); - OutBuffer[FrontLeft][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; - OutBuffer[FrontRight][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; - OutPos++; - } - - Delay[0] >>= HRTFDELAY_BITS; - Delay[1] >>= HRTFDELAY_BITS; - for(;pos < BufferSize;pos++) - { - hrtfstate->History[Offset&SRC_HISTORY_MASK] = data[pos]; - left = hrtfstate->History[(Offset-Delay[0])&SRC_HISTORY_MASK]; - right = hrtfstate->History[(Offset-Delay[1])&SRC_HISTORY_MASK]; - - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; - Offset++; - - ApplyCoeffs(Offset, hrtfstate->Values, IrSize, Coeffs, left, right); - OutBuffer[FrontLeft][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][0]; - OutBuffer[FrontRight][OutPos] += hrtfstate->Values[Offset&HRIR_MASK][1]; - - OutPos++; - } -} - - -#undef MixHrtf - -#undef MERGE -#undef REAL_MERGE diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_neon.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer_neon.c deleted file mode 100644 index 7b6da2b9..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_neon.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "config.h" - -#include - -#include "AL/al.h" -#include "AL/alc.h" -#include "alMain.h" -#include "alu.h" -#include "hrtf.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; - 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]); - float32x4_t deltas = vld1q_f32(&CoeffStep[c][0]); - - vals = vmlaq_f32(vals, coefs, leftright4); - coefs = vaddq_f32(coefs, deltas); - - vst1_f32((float32_t*)&Values[o0][0], vget_low_f32(vals)); - vst1_f32((float32_t*)&Values[o1][0], vget_high_f32(vals)); - vst1q_f32(&Coeffs[c][0], coefs); - } -} - -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 - - -void MixDirect_Neon(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) -{ - ALfloat gain, step; - float32x4_t gain4; - ALuint c; - - for(c = 0;c < OutChans;c++) - { - ALuint pos = 0; - gain = Gains[c].Current; - step = Gains[c].Step; - if(step != 1.0f && Counter > 0) - { - for(;pos < BufferSize && pos < Counter;pos++) - { - OutBuffer[c][OutPos+pos] += data[pos]*gain; - gain *= step; - } - if(pos == Counter) - gain = Gains[c].Target; - Gains[c].Current = gain; - /* Mix until pos is aligned with 4 or the mix is done. */ - for(;pos < BufferSize && (pos&3) != 0;pos++) - OutBuffer[c][OutPos+pos] += data[pos]*gain; - } - - if(!(gain > GAIN_SILENCE_THRESHOLD)) - continue; - gain4 = vdupq_n_f32(gain); - for(;BufferSize-pos > 3;pos += 4) - { - const float32x4_t val4 = vld1q_f32(&data[pos]); - float32x4_t dry4 = vld1q_f32(&OutBuffer[c][OutPos+pos]); - dry4 = vaddq_f32(dry4, vmulq_f32(val4, gain4)); - vst1q_f32(&OutBuffer[c][OutPos+pos], dry4); - } - for(;pos < BufferSize;pos++) - OutBuffer[c][OutPos+pos] += data[pos]*gain; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse.c deleted file mode 100644 index 970619ec..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse.c +++ /dev/null @@ -1,202 +0,0 @@ -#include "config.h" - -#ifdef IN_IDE_PARSER -/* KDevelop's parser won't recognize these defines that get added by the -msse - * switch used to compile this source. Without them, xmmintrin.h fails to - * declare anything. */ -#define __MMX__ -#define __SSE__ -#endif -#include - -#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 = _mm_setr_ps(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 = _mm_setr_ps(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 Mix_SSE(const ALfloat *data, ALuint OutChans, ALfloat (*restrict OutBuffer)[BUFFERSIZE], - MixGains *Gains, ALuint Counter, ALuint OutPos, ALuint BufferSize) -{ - ALfloat gain, step; - __m128 gain4, step4; - ALuint c; - - for(c = 0;c < OutChans;c++) - { - ALuint pos = 0; - gain = Gains[c].Current; - step = Gains[c].Step; - if(step != 1.0f && Counter > 0) - { - /* Mix with applying gain steps in aligned multiples of 4. */ - if(BufferSize-pos > 3 && Counter-pos > 3) - { - gain4 = _mm_setr_ps( - gain, - gain * step, - gain * step * step, - gain * step * step * step - ); - step4 = _mm_set1_ps(step * step * step * step); - do { - const __m128 val4 = _mm_load_ps(&data[pos]); - __m128 dry4 = _mm_load_ps(&OutBuffer[c][OutPos+pos]); - dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain4)); - gain4 = _mm_mul_ps(gain4, step4); - _mm_store_ps(&OutBuffer[c][OutPos+pos], dry4); - pos += 4; - } while(BufferSize-pos > 3 && Counter-pos > 3); - gain = _mm_cvtss_f32(gain4); - } - /* Mix with applying left over gain steps that aren't aligned multiples of 4. */ - for(;pos < BufferSize && pos < Counter;pos++) - { - OutBuffer[c][OutPos+pos] += data[pos]*gain; - gain *= step; - } - if(pos == Counter) - gain = Gains[c].Target; - Gains[c].Current = gain; - /* Mix until pos is aligned with 4 or the mix is done. */ - for(;pos < BufferSize && (pos&3) != 0;pos++) - OutBuffer[c][OutPos+pos] += data[pos]*gain; - } - - if(!(gain > GAIN_SILENCE_THRESHOLD)) - continue; - gain4 = _mm_set1_ps(gain); - for(;BufferSize-pos > 3;pos += 4) - { - const __m128 val4 = _mm_load_ps(&data[pos]); - __m128 dry4 = _mm_load_ps(&OutBuffer[c][OutPos+pos]); - dry4 = _mm_add_ps(dry4, _mm_mul_ps(val4, gain4)); - _mm_store_ps(&OutBuffer[c][OutPos+pos], dry4); - } - for(;pos < BufferSize;pos++) - OutBuffer[c][OutPos+pos] += data[pos]*gain; - } -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse41.c b/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse41.c deleted file mode 100644 index 8ce8cd90..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/mixer_sse41.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 2014 by Timothy Arceri . - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include "alu.h" -#include "mixer_defs.h" - - -const ALfloat *Resample_lerp32_SSE41(const ALfloat *src, ALuint frac, ALuint increment, - ALfloat *restrict dst, ALuint numsamples) -{ - const __m128i increment4 = _mm_set1_epi32(increment*4); - const __m128 fracOne4 = _mm_set1_ps(1.0f/FRACTIONONE); - const __m128i fracMask4 = _mm_set1_epi32(FRACTIONMASK); - alignas(16) union { ALuint i[4]; float f[4]; } pos_; - alignas(16) union { ALuint i[4]; float f[4]; } frac_; - __m128i frac4, pos4; - ALuint pos; - ALuint i; - - InitiatePositionArrays(frac, increment, frac_.i, pos_.i, 4); - - frac4 = _mm_castps_si128(_mm_load_ps(frac_.f)); - pos4 = _mm_castps_si128(_mm_load_ps(pos_.f)); - - for(i = 0;numsamples-i > 3;i += 4) - { - const __m128 val1 = _mm_setr_ps(src[pos_.i[0]], src[pos_.i[1]], src[pos_.i[2]], src[pos_.i[3]]); - const __m128 val2 = _mm_setr_ps(src[pos_.i[0]+1], src[pos_.i[1]+1], src[pos_.i[2]+1], src[pos_.i[3]+1]); - - /* val1 + (val2-val1)*mu */ - const __m128 r0 = _mm_sub_ps(val2, val1); - const __m128 mu = _mm_mul_ps(_mm_cvtepi32_ps(frac4), fracOne4); - const __m128 out = _mm_add_ps(val1, _mm_mul_ps(mu, r0)); - - _mm_store_ps(&dst[i], out); - - frac4 = _mm_add_epi32(frac4, increment4); - pos4 = _mm_add_epi32(pos4, _mm_srli_epi32(frac4, FRACTIONBITS)); - frac4 = _mm_and_si128(frac4, fracMask4); - - pos_.i[0] = _mm_extract_epi32(pos4, 0); - pos_.i[1] = _mm_extract_epi32(pos4, 1); - pos_.i[2] = _mm_extract_epi32(pos4, 2); - pos_.i[3] = _mm_extract_epi32(pos4, 3); - } - - pos = pos_.i[0]; - frac = _mm_cvtsi128_si32(frac4); - - for(;i < numsamples;i++) - { - dst[i] = lerp(src[pos], src[pos+1], frac * (1.0f/FRACTIONONE)); - - frac += increment; - pos += frac>>FRACTIONBITS; - frac &= FRACTIONMASK; - } - return dst; -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/panning.c b/love/src/jni/openal-soft-1.17.0/Alc/panning.c deleted file mode 100644 index 30a1e571..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/panning.c +++ /dev/null @@ -1,450 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2010 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include -#include -#include - -#include "alMain.h" -#include "AL/al.h" -#include "AL/alc.h" -#include "alu.h" - -extern inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxChannels]); - -static void SetSpeakerArrangement(const char *name, ALfloat SpeakerAngle[MaxChannels], - enum Channel Speaker2Chan[MaxChannels], ALint chans) -{ - char *confkey, *next; - char *layout_str; - char *sep, *end; - enum Channel val; - const char *str; - int i; - - if(!ConfigValueStr(NULL, name, &str) && !ConfigValueStr(NULL, "layout", &str)) - return; - - layout_str = strdup(str); - next = confkey = layout_str; - while(next && *next) - { - confkey = next; - next = strchr(confkey, ','); - if(next) - { - *next = 0; - do { - next++; - } while(isspace(*next) || *next == ','); - } - - sep = strchr(confkey, '='); - if(!sep || confkey == sep) - { - ERR("Malformed speaker key: %s\n", confkey); - continue; - } - - end = sep - 1; - while(isspace(*end) && end != confkey) - end--; - *(++end) = 0; - - if(strcmp(confkey, "fl") == 0 || strcmp(confkey, "front-left") == 0) - val = FrontLeft; - else if(strcmp(confkey, "fr") == 0 || strcmp(confkey, "front-right") == 0) - val = FrontRight; - else if(strcmp(confkey, "fc") == 0 || strcmp(confkey, "front-center") == 0) - val = FrontCenter; - else if(strcmp(confkey, "bl") == 0 || strcmp(confkey, "back-left") == 0) - val = BackLeft; - else if(strcmp(confkey, "br") == 0 || strcmp(confkey, "back-right") == 0) - val = BackRight; - else if(strcmp(confkey, "bc") == 0 || strcmp(confkey, "back-center") == 0) - val = BackCenter; - else if(strcmp(confkey, "sl") == 0 || strcmp(confkey, "side-left") == 0) - val = SideLeft; - else if(strcmp(confkey, "sr") == 0 || strcmp(confkey, "side-right") == 0) - val = SideRight; - else - { - ERR("Unknown speaker for %s: \"%s\"\n", name, confkey); - continue; - } - - *(sep++) = 0; - while(isspace(*sep)) - sep++; - - for(i = 0;i < chans;i++) - { - if(Speaker2Chan[i] == val) - { - long angle = strtol(sep, NULL, 10); - if(angle >= -180 && angle <= 180) - SpeakerAngle[i] = DEG2RAD(angle); - else - ERR("Invalid angle for speaker \"%s\": %ld\n", confkey, angle); - break; - } - } - } - free(layout_str); - layout_str = NULL; - - for(i = 0;i < chans;i++) - { - int min = i; - int i2; - - for(i2 = i+1;i2 < chans;i2++) - { - if(SpeakerAngle[i2] < SpeakerAngle[min]) - min = i2; - } - - if(min != i) - { - ALfloat tmpf; - enum Channel tmpc; - - tmpf = SpeakerAngle[i]; - SpeakerAngle[i] = SpeakerAngle[min]; - SpeakerAngle[min] = tmpf; - - tmpc = Speaker2Chan[i]; - Speaker2Chan[i] = Speaker2Chan[min]; - Speaker2Chan[min] = tmpc; - } - } -} - - -void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]) -{ - 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 < MaxChannels;i++) - gains[i] = 0.0f; - 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 < MaxChannels;i++) - gains[i] = 0.0f; - 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_2PI; - a = (angle-SpeakerAngle[i]) / - (F_2PI + 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; - 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_2PI; - 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; - 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_2PI; - 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_2PI + rangle-SpeakerAngle[last]) / - (F_2PI + SpeakerAngle[i]-SpeakerAngle[last]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, a); - } - else if(SpeakerAngle[last] < rangle) - { - a = (rangle-SpeakerAngle[last]) / - (F_2PI + 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_2PI + SpeakerAngle[0]-SpeakerAngle[i]); - tmpgains[chan] = lerp(tmpgains[chan], 1.0f, 1.0f-a); - } - else if(SpeakerAngle[0] > langle) - { - a = (F_2PI + langle-SpeakerAngle[i]) / - (F_2PI + 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; - } -} - - -ALvoid aluInitPanning(ALCdevice *Device) -{ - const char *layoutname = NULL; - enum Channel *Speaker2Chan; - ALfloat *SpeakerAngle; - - Speaker2Chan = Device->Speaker2Chan; - SpeakerAngle = Device->SpeakerAngle; - switch(Device->FmtChans) - { - case DevFmtMono: - Device->NumChan = 1; - Speaker2Chan[0] = FrontCenter; - SpeakerAngle[0] = DEG2RAD(0.0f); - layoutname = NULL; - break; - - case DevFmtStereo: - Device->NumChan = 2; - Speaker2Chan[0] = FrontLeft; - Speaker2Chan[1] = FrontRight; - SpeakerAngle[0] = DEG2RAD(-90.0f); - SpeakerAngle[1] = DEG2RAD( 90.0f); - layoutname = "layout_stereo"; - break; - - case DevFmtQuad: - Device->NumChan = 4; - Speaker2Chan[0] = BackLeft; - Speaker2Chan[1] = FrontLeft; - Speaker2Chan[2] = FrontRight; - Speaker2Chan[3] = BackRight; - SpeakerAngle[0] = DEG2RAD(-135.0f); - SpeakerAngle[1] = DEG2RAD( -45.0f); - SpeakerAngle[2] = DEG2RAD( 45.0f); - SpeakerAngle[3] = DEG2RAD( 135.0f); - layoutname = "layout_quad"; - break; - - case DevFmtX51: - Device->NumChan = 5; - Speaker2Chan[0] = BackLeft; - Speaker2Chan[1] = FrontLeft; - Speaker2Chan[2] = FrontCenter; - Speaker2Chan[3] = FrontRight; - Speaker2Chan[4] = BackRight; - SpeakerAngle[0] = DEG2RAD(-110.0f); - SpeakerAngle[1] = DEG2RAD( -30.0f); - SpeakerAngle[2] = DEG2RAD( 0.0f); - SpeakerAngle[3] = DEG2RAD( 30.0f); - SpeakerAngle[4] = DEG2RAD( 110.0f); - layoutname = "layout_surround51"; - break; - - case DevFmtX51Side: - Device->NumChan = 5; - Speaker2Chan[0] = SideLeft; - Speaker2Chan[1] = FrontLeft; - Speaker2Chan[2] = FrontCenter; - Speaker2Chan[3] = FrontRight; - Speaker2Chan[4] = SideRight; - SpeakerAngle[0] = DEG2RAD(-90.0f); - SpeakerAngle[1] = DEG2RAD(-30.0f); - SpeakerAngle[2] = DEG2RAD( 0.0f); - SpeakerAngle[3] = DEG2RAD( 30.0f); - SpeakerAngle[4] = DEG2RAD( 90.0f); - layoutname = "layout_side51"; - break; - - case DevFmtX61: - Device->NumChan = 6; - Speaker2Chan[0] = SideLeft; - Speaker2Chan[1] = FrontLeft; - Speaker2Chan[2] = FrontCenter; - Speaker2Chan[3] = FrontRight; - Speaker2Chan[4] = SideRight; - Speaker2Chan[5] = BackCenter; - SpeakerAngle[0] = DEG2RAD(-90.0f); - SpeakerAngle[1] = DEG2RAD(-30.0f); - SpeakerAngle[2] = DEG2RAD( 0.0f); - SpeakerAngle[3] = DEG2RAD( 30.0f); - SpeakerAngle[4] = DEG2RAD( 90.0f); - SpeakerAngle[5] = DEG2RAD(180.0f); - layoutname = "layout_surround61"; - break; - - case DevFmtX71: - Device->NumChan = 7; - Speaker2Chan[0] = BackLeft; - Speaker2Chan[1] = SideLeft; - Speaker2Chan[2] = FrontLeft; - Speaker2Chan[3] = FrontCenter; - Speaker2Chan[4] = FrontRight; - Speaker2Chan[5] = SideRight; - Speaker2Chan[6] = BackRight; - SpeakerAngle[0] = DEG2RAD(-150.0f); - SpeakerAngle[1] = DEG2RAD( -90.0f); - SpeakerAngle[2] = DEG2RAD( -30.0f); - SpeakerAngle[3] = DEG2RAD( 0.0f); - SpeakerAngle[4] = DEG2RAD( 30.0f); - SpeakerAngle[5] = DEG2RAD( 90.0f); - SpeakerAngle[6] = DEG2RAD( 150.0f); - layoutname = "layout_surround71"; - break; - } - if(layoutname && Device->Type != Loopback) - SetSpeakerArrangement(layoutname, SpeakerAngle, Speaker2Chan, Device->NumChan); -} diff --git a/love/src/jni/openal-soft-1.17.0/Alc/vector.h b/love/src/jni/openal-soft-1.17.0/Alc/vector.h deleted file mode 100644 index 9f28d0db..00000000 --- a/love/src/jni/openal-soft-1.17.0/Alc/vector.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef AL_VECTOR_H -#define AL_VECTOR_H - -#include - -#include - -/* "Base" vector type, designed to alias with the actual vector types. */ -typedef struct vector__s { - ALsizei Capacity; - ALsizei Size; -} *vector_; - -#define TYPEDEF_VECTOR(T, N) typedef struct { \ - ALsizei Capacity; \ - ALsizei Size; \ - T Data[]; \ -} _##N; \ -typedef _##N* N; \ -typedef const _##N* const_##N; - -#define VECTOR(T) struct { \ - ALsizei Capacity; \ - ALsizei Size; \ - T Data[]; \ -}* - -#define VECTOR_INIT(_x) do { (_x) = NULL; } while(0) -#define VECTOR_INIT_STATIC() NULL -#define VECTOR_DEINIT(_x) do { free((_x)); (_x) = NULL; } while(0) - -/* Helper to increase a vector's reserve. Do not call directly. */ -ALboolean vector_reserve(char *ptr, size_t base_size, size_t obj_size, ALsizei obj_count, ALboolean exact); -#define VECTOR_RESERVE(_x, _c) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c), AL_TRUE)) - -ALboolean vector_resize(char *ptr, size_t base_size, size_t obj_size, ALsizei obj_count); -#define VECTOR_RESIZE(_x, _c) (vector_resize((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_c))) - -#define VECTOR_CAPACITY(_x) ((_x) ? (_x)->Capacity : 0) -#define VECTOR_SIZE(_x) ((_x) ? (_x)->Size : 0) - -#define VECTOR_ITER_BEGIN(_x) ((_x) ? (_x)->Data + 0 : NULL) -#define VECTOR_ITER_END(_x) ((_x) ? (_x)->Data + (_x)->Size : NULL) - -ALboolean vector_insert(char *ptr, size_t base_size, size_t obj_size, void *ins_pos, const void *datstart, const void *datend); -#ifdef __GNUC__ -#define TYPE_CHECK(T1, T2) __builtin_types_compatible_p(T1, T2) -#define VECTOR_INSERT(_x, _i, _s, _e) __extension__({ \ - ALboolean _r; \ - static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_i))), "Incompatible insertion iterator"); \ - static_assert(TYPE_CHECK(__typeof((_x)->Data[0]), __typeof(*(_s))), "Incompatible insertion source type"); \ - static_assert(TYPE_CHECK(__typeof(*(_s)), __typeof(*(_e))), "Incompatible iterator sources"); \ - _r = vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e)); \ - _r; \ -}) -#else -#define VECTOR_INSERT(_x, _i, _s, _e) (vector_insert((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), (_i), (_s), (_e))) -#endif - -#define VECTOR_PUSH_BACK(_x, _obj) (vector_reserve((char*)&(_x), sizeof(*(_x)), sizeof((_x)->Data[0]), VECTOR_SIZE(_x)+1, AL_FALSE) && \ - (((_x)->Data[(_x)->Size++] = (_obj)),AL_TRUE)) -#define VECTOR_POP_BACK(_x) ((void)((_x)->Size--)) - -#define VECTOR_BACK(_x) ((_x)->Data[(_x)->Size-1]) -#define VECTOR_FRONT(_x) ((_x)->Data[0]) - -#define VECTOR_ELEM(_x, _o) ((_x)->Data[(_o)]) - -#define VECTOR_FOR_EACH(_t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ - for(;_iter != _end;++_iter) \ - _f(_iter); \ -} while(0) - -#define VECTOR_FIND_IF(_i, _t, _x, _f) do { \ - _t *_iter = VECTOR_ITER_BEGIN((_x)); \ - _t *_end = VECTOR_ITER_END((_x)); \ - for(;_iter != _end;++_iter) \ - { \ - if(_f(_iter)) \ - break; \ - } \ - (_i) = _iter; \ -} while(0) - -#endif /* AL_VECTOR_H */ diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alFilter.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alFilter.h deleted file mode 100644 index 62b5fda8..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alFilter.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef _AL_FILTER_H_ -#define _AL_FILTER_H_ - -#include "alMain.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define LOWPASSFREQREF (5000.0f) -#define HIGHPASSFREQREF (250.0f) - - -/* Filters implementation is based on the "Cookbook formulae for audio * - * EQ biquad filter coefficients" by Robert Bristow-Johnson * - * http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt */ - -typedef enum ALfilterType { - /** EFX-style low-pass filter, specifying a gain and reference frequency. */ - ALfilterType_HighShelf, - /** EFX-style high-pass filter, specifying a gain and reference frequency. */ - ALfilterType_LowShelf, - /** Peaking filter, specifying a gain, reference frequency, and bandwidth. */ - ALfilterType_Peaking, - - /** Low-pass cut-off filter, specifying a cut-off frequency and bandwidth. */ - ALfilterType_LowPass, - /** High-pass cut-off filter, specifying a cut-off frequency and bandwidth. */ - ALfilterType_HighPass, - /** Band-pass filter, specifying a center frequency and bandwidth. */ - ALfilterType_BandPass, -} ALfilterType; - -typedef struct ALfilterState { - ALfloat x[2]; /* History of two last input samples */ - ALfloat y[2]; /* History of two last output samples */ - ALfloat a[3]; /* Transfer function coefficients "a" */ - ALfloat b[3]; /* Transfer function coefficients "b" */ - - void (*process)(struct ALfilterState *self, ALfloat *restrict dst, const ALfloat *src, ALuint numsamples); -} ALfilterState; -#define ALfilterState_process(a, ...) ((a)->process((a), __VA_ARGS__)) - -void ALfilterState_clear(ALfilterState *filter); -void ALfilterState_setParams(ALfilterState *filter, ALfilterType type, ALfloat gain, ALfloat freq_mult, ALfloat bandwidth); - -inline ALfloat ALfilterState_processSingle(ALfilterState *filter, ALfloat sample) -{ - ALfloat outsmp; - - outsmp = filter->b[0] * sample + - filter->b[1] * filter->x[0] + - filter->b[2] * filter->x[1] - - filter->a[1] * filter->y[0] - - filter->a[2] * filter->y[1]; - filter->x[1] = filter->x[0]; - filter->x[0] = sample; - filter->y[1] = filter->y[0]; - filter->y[0] = outsmp; - - return outsmp; -} - -void ALfilterState_processC(ALfilterState *filter, ALfloat *restrict dst, const ALfloat *src, ALuint numsamples); - - -typedef struct ALfilter { - // Filter type (AL_FILTER_NULL, ...) - ALenum type; - - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - - void (*SetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint val); - void (*SetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALint *vals); - void (*SetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat val); - void (*SetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, const ALfloat *vals); - - void (*GetParami)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *val); - void (*GetParamiv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALint *vals); - void (*GetParamf)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *val); - void (*GetParamfv)(struct ALfilter *filter, ALCcontext *context, ALenum param, ALfloat *vals); - - /* Self ID */ - ALuint id; -} ALfilter; - -#define ALfilter_SetParami(x, c, p, v) ((x)->SetParami((x),(c),(p),(v))) -#define ALfilter_SetParamiv(x, c, p, v) ((x)->SetParamiv((x),(c),(p),(v))) -#define ALfilter_SetParamf(x, c, p, v) ((x)->SetParamf((x),(c),(p),(v))) -#define ALfilter_SetParamfv(x, c, p, v) ((x)->SetParamfv((x),(c),(p),(v))) - -#define ALfilter_GetParami(x, c, p, v) ((x)->GetParami((x),(c),(p),(v))) -#define ALfilter_GetParamiv(x, c, p, v) ((x)->GetParamiv((x),(c),(p),(v))) -#define ALfilter_GetParamf(x, c, p, v) ((x)->GetParamf((x),(c),(p),(v))) -#define ALfilter_GetParamfv(x, c, p, v) ((x)->GetParamfv((x),(c),(p),(v))) - -inline struct ALfilter *LookupFilter(ALCdevice *device, ALuint id) -{ return (struct ALfilter*)LookupUIntMapKey(&device->FilterMap, id); } -inline struct ALfilter *RemoveFilter(ALCdevice *device, ALuint id) -{ return (struct ALfilter*)RemoveUIntMapKey(&device->FilterMap, id); } - -ALvoid ReleaseALFilters(ALCdevice *device); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alListener.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alListener.h deleted file mode 100644 index ee07d87c..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alListener.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _AL_LISTENER_H_ -#define _AL_LISTENER_H_ - -#include "alMain.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ALlistener { - volatile ALfloat Position[3]; - volatile ALfloat Velocity[3]; - volatile ALfloat Forward[3]; - volatile ALfloat Up[3]; - volatile ALfloat Gain; - volatile ALfloat MetersPerUnit; - - struct { - ALfloat Matrix[4][4]; - ALfloat Velocity[3]; - } Params; -} ALlistener; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMain.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMain.h deleted file mode 100644 index 111dde95..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMain.h +++ /dev/null @@ -1,895 +0,0 @@ -#ifndef AL_MAIN_H -#define AL_MAIN_H - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_STRINGS_H -#include -#endif - -#ifdef HAVE_FENV_H -#include -#endif - -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" - - -#if defined(_WIN64) -#define SZFMT "%I64u" -#elif defined(_WIN32) -#define SZFMT "%u" -#else -#define SZFMT "%zu" -#endif - - -#include "static_assert.h" -#include "align.h" -#include "atomic.h" -#include "uintmap.h" -#include "vector.h" -#include "alstring.h" - -#ifndef ALC_SOFT_HRTF -#define ALC_SOFT_HRTF 1 -#define ALC_HRTF_SOFT 0x1992 -#endif - -#ifndef ALC_SOFT_midi_interface -#define ALC_SOFT_midi_interface 1 -/* Global properties */ -#define AL_MIDI_CLOCK_SOFT 0x9999 -#define AL_MIDI_STATE_SOFT 0x9986 -#define AL_MIDI_GAIN_SOFT 0x9998 -#define AL_SOUNDFONTS_SIZE_SOFT 0x9995 -#define AL_SOUNDFONTS_SOFT 0x9994 - -/* Soundfont properties */ -#define AL_PRESETS_SIZE_SOFT 0x9993 -#define AL_PRESETS_SOFT 0x9992 - -/* Preset properties */ -#define AL_MIDI_PRESET_SOFT 0x9997 -#define AL_MIDI_BANK_SOFT 0x9996 -#define AL_FONTSOUNDS_SIZE_SOFT 0x9991 -#define AL_FONTSOUNDS_SOFT 0x9990 - -/* Fontsound properties */ -/* AL_BUFFER */ -#define AL_SAMPLE_START_SOFT 0x2000 -#define AL_SAMPLE_END_SOFT 0x2001 -#define AL_SAMPLE_LOOP_START_SOFT 0x2002 -#define AL_SAMPLE_LOOP_END_SOFT 0x2003 -#define AL_SAMPLE_RATE_SOFT 0x2004 -#define AL_BASE_KEY_SOFT 0x2005 -#define AL_KEY_CORRECTION_SOFT 0x2006 -#define AL_SAMPLE_TYPE_SOFT 0x2007 -#define AL_FONTSOUND_LINK_SOFT 0x2008 -#define AL_MOD_LFO_TO_PITCH_SOFT 0x0005 -#define AL_VIBRATO_LFO_TO_PITCH_SOFT 0x0006 -#define AL_MOD_ENV_TO_PITCH_SOFT 0x0007 -#define AL_FILTER_CUTOFF_SOFT 0x0008 -#define AL_FILTER_RESONANCE_SOFT 0x0009 -#define AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT 0x000A -#define AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT 0x000B -#define AL_MOD_LFO_TO_VOLUME_SOFT 0x000D -#define AL_CHORUS_SEND_SOFT 0x000F -#define AL_REVERB_SEND_SOFT 0x0010 -#define AL_PAN_SOFT 0x0011 -#define AL_MOD_LFO_DELAY_SOFT 0x0015 -#define AL_MOD_LFO_FREQUENCY_SOFT 0x0016 -#define AL_VIBRATO_LFO_DELAY_SOFT 0x0017 -#define AL_VIBRATO_LFO_FREQUENCY_SOFT 0x0018 -#define AL_MOD_ENV_DELAYTIME_SOFT 0x0019 -#define AL_MOD_ENV_ATTACKTIME_SOFT 0x001A -#define AL_MOD_ENV_HOLDTIME_SOFT 0x001B -#define AL_MOD_ENV_DECAYTIME_SOFT 0x001C -#define AL_MOD_ENV_SUSTAINVOLUME_SOFT 0x001D -#define AL_MOD_ENV_RELEASETIME_SOFT 0x002E -#define AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT 0x001F -#define AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT 0x0020 -#define AL_VOLUME_ENV_DELAYTIME_SOFT 0x0021 -#define AL_VOLUME_ENV_ATTACKTIME_SOFT 0x0022 -#define AL_VOLUME_ENV_HOLDTIME_SOFT 0x0023 -#define AL_VOLUME_ENV_DECAYTIME_SOFT 0x0024 -#define AL_VOLUME_ENV_SUSTAINVOLUME_SOFT 0x0025 -#define AL_VOLUME_ENV_RELEASETIME_SOFT 0x0026 -#define AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT 0x0027 -#define AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT 0x0028 -#define AL_KEY_RANGE_SOFT 0x002B -#define AL_VELOCITY_RANGE_SOFT 0x002C -#define AL_ATTENUATION_SOFT 0x0030 -#define AL_TUNING_COARSE_SOFT 0x0033 -#define AL_TUNING_FINE_SOFT 0x0034 -#define AL_LOOP_MODE_SOFT 0x0036 -#define AL_TUNING_SCALE_SOFT 0x0038 -#define AL_EXCLUSIVE_CLASS_SOFT 0x0039 - -/* Sample Types */ -/* AL_MONO_SOFT */ -#define AL_RIGHT_SOFT 0x0002 -#define AL_LEFT_SOFT 0x0004 - -/* Loop Modes */ -/* AL_NONE */ -#define AL_LOOP_CONTINUOUS_SOFT 0x0001 -#define AL_LOOP_UNTIL_RELEASE_SOFT 0x0003 - -/* Fontsound modulator stage properties */ -#define AL_SOURCE0_INPUT_SOFT 0x998F -#define AL_SOURCE0_TYPE_SOFT 0x998E -#define AL_SOURCE0_FORM_SOFT 0x998D -#define AL_SOURCE1_INPUT_SOFT 0x998C -#define AL_SOURCE1_TYPE_SOFT 0x998B -#define AL_SOURCE1_FORM_SOFT 0x998A -#define AL_AMOUNT_SOFT 0x9989 -#define AL_TRANSFORM_OP_SOFT 0x9988 -#define AL_DESTINATION_SOFT 0x9987 - -/* Sounce Inputs */ -#define AL_ONE_SOFT 0x0080 -#define AL_NOTEON_VELOCITY_SOFT 0x0082 -#define AL_NOTEON_KEY_SOFT 0x0083 -/* AL_KEYPRESSURE_SOFT */ -/* AL_CHANNELPRESSURE_SOFT */ -/* AL_PITCHBEND_SOFT */ -#define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090 -/* CC 0...127 */ - -/* Source Types */ -#define AL_UNORM_SOFT 0x0000 -#define AL_UNORM_REV_SOFT 0x0100 -#define AL_SNORM_SOFT 0x0200 -#define AL_SNORM_REV_SOFT 0x0300 - -/* Source Forms */ -#define AL_LINEAR_SOFT 0x0000 -#define AL_CONCAVE_SOFT 0x0400 -#define AL_CONVEX_SOFT 0x0800 -#define AL_SWITCH_SOFT 0x0C00 - -/* Transform Ops */ -/* AL_LINEAR_SOFT */ -#define AL_ABSOLUTE_SOFT 0x0002 - -/* Events */ -#define AL_NOTEOFF_SOFT 0x0080 -#define AL_NOTEON_SOFT 0x0090 -#define AL_KEYPRESSURE_SOFT 0x00A0 -#define AL_CONTROLLERCHANGE_SOFT 0x00B0 -#define AL_PROGRAMCHANGE_SOFT 0x00C0 -#define AL_CHANNELPRESSURE_SOFT 0x00D0 -#define AL_PITCHBEND_SOFT 0x00E0 - -typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids); -typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids); -typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id); -typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values); -typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids); -typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids); -typedef void (AL_APIENTRY*LPALDELETEPRESETSSOFT)(ALsizei n, const ALuint *ids); -typedef ALboolean (AL_APIENTRY*LPALISPRESETSOFT)(ALuint id); -typedef void (AL_APIENTRY*LPALPRESETISOFT)(ALuint id, ALenum param, ALint value); -typedef void (AL_APIENTRY*LPALPRESETIVSOFT)(ALuint id, ALenum param, const ALint *values); -typedef void (AL_APIENTRY*LPALPRESETFONTSOUNDSSOFT)(ALuint id, ALsizei count, const ALuint *fsids); -typedef void (AL_APIENTRY*LPALGETPRESETIVSOFT)(ALuint id, ALenum param, ALint *values); -typedef void (AL_APIENTRY*LPALGENFONTSOUNDSSOFT)(ALsizei n, ALuint *ids); -typedef void (AL_APIENTRY*LPALDELETEFONTSOUNDSSOFT)(ALsizei n, const ALuint *ids); -typedef ALboolean (AL_APIENTRY*LPALISFONTSOUNDSOFT)(ALuint id); -typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint value); -typedef void (AL_APIENTRY*LPALFONTSOUND2ISOFT)(ALuint id, ALenum param, ALint value1, ALint value2); -typedef void (AL_APIENTRY*LPALFONTSOUNDIVSOFT)(ALuint id, ALenum param, const ALint *values); -typedef void (AL_APIENTRY*LPALGETFONTSOUNDIVSOFT)(ALuint id, ALenum param, ALint *values); -typedef void (AL_APIENTRY*LPALFONTSOUNDMOFULATORISOFT)(ALuint id, ALsizei stage, ALenum param, ALint value); -typedef void (AL_APIENTRY*LPALGETFONTSOUNDMODULATORIVSOFT)(ALuint id, ALsizei stage, ALenum param, ALint *values); -typedef void (AL_APIENTRY*LPALMIDISOUNDFONTSOFT)(ALuint id); -typedef void (AL_APIENTRY*LPALMIDISOUNDFONTVSOFT)(ALsizei count, const ALuint *ids); -typedef void (AL_APIENTRY*LPALMIDIEVENTSOFT)(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); -typedef void (AL_APIENTRY*LPALMIDISYSEXSOFT)(ALuint64SOFT time, const ALbyte *data, ALsizei size); -typedef void (AL_APIENTRY*LPALMIDIPLAYSOFT)(void); -typedef void (AL_APIENTRY*LPALMIDIPAUSESOFT)(void); -typedef void (AL_APIENTRY*LPALMIDISTOPSOFT)(void); -typedef void (AL_APIENTRY*LPALMIDIRESETSOFT)(void); -typedef void (AL_APIENTRY*LPALMIDIGAINSOFT)(ALfloat value); -typedef ALint64SOFT (AL_APIENTRY*LPALGETINTEGER64SOFT)(ALenum pname); -typedef void (AL_APIENTRY*LPALGETINTEGER64VSOFT)(ALenum pname, ALint64SOFT *values); -typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user); -#ifdef AL_ALEXT_PROTOTYPES -AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids); -AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids); -AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id); -AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values); -AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids); - -AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids); -AL_API void AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids); -AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id); -AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value); -AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values); -AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values); -AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids); - -AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids); -AL_API void AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids); -AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id); -AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value); -AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2); -AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values); -AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values); -AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value); -AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values); - -AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id); -AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids); -AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2); -AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size); -AL_API void AL_APIENTRY alMidiPlaySOFT(void); -AL_API void AL_APIENTRY alMidiPauseSOFT(void); -AL_API void AL_APIENTRY alMidiStopSOFT(void); -AL_API void AL_APIENTRY alMidiResetSOFT(void); -AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value); -AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname); -AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values); -AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user); -#endif -#endif - -#ifndef ALC_SOFT_device_clock -#define ALC_SOFT_device_clock 1 -typedef int64_t ALCint64SOFT; -typedef uint64_t ALCuint64SOFT; -#define ALC_DEVICE_CLOCK_SOFT 0x1600 -typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values); -#ifdef AL_ALEXT_PROTOTYPES -ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values); -#endif -#endif - - -#ifdef IN_IDE_PARSER -/* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but - * recent versions (at least 4.5.1) do recognize GCC's __restrict. */ -#define restrict __restrict -#endif - - -typedef ALint64SOFT ALint64; -typedef ALuint64SOFT ALuint64; - -typedef ptrdiff_t ALintptrEXT; -typedef ptrdiff_t ALsizeiptrEXT; - -#ifndef U64 -#if defined(_MSC_VER) -#define U64(x) ((ALuint64)(x##ui64)) -#elif SIZEOF_LONG == 8 -#define U64(x) ((ALuint64)(x##ul)) -#elif SIZEOF_LONG_LONG == 8 -#define U64(x) ((ALuint64)(x##ull)) -#endif -#endif - -#ifndef UINT64_MAX -#define UINT64_MAX U64(18446744073709551615) -#endif - -#ifndef UNUSED -#if defined(__cplusplus) -#define UNUSED(x) -#elif defined(__GNUC__) -#define UNUSED(x) UNUSED_##x __attribute__((unused)) -#elif defined(__LCLINT__) -#define UNUSED(x) /*@unused@*/ x -#else -#define UNUSED(x) x -#endif -#endif - -#ifdef __GNUC__ -#define DECL_CONST __attribute__((const)) -#define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z)))) -#else -#define DECL_CONST -#define DECL_FORMAT(x, y, z) -#endif - -#if defined(__GNUC__) && defined(__i386__) -/* force_align_arg_pointer is required for proper function arguments aligning - * when SSE code is used. Some systems (Windows, QNX) do not guarantee our - * thread functions will be properly aligned on the stack, even though GCC may - * generate code with the assumption that it is. */ -#define FORCE_ALIGN __attribute__((force_align_arg_pointer)) -#else -#define FORCE_ALIGN -#endif - -#ifdef HAVE_C99_VLA -#define DECL_VLA(T, _name, _size) T _name[(_size)] -#else -#define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T)) -#endif - -#ifndef PATH_MAX -#ifdef MAX_PATH -#define PATH_MAX MAX_PATH -#else -#define PATH_MAX 4096 -#endif -#endif - - -static const union { - ALuint u; - ALubyte b[sizeof(ALuint)]; -} EndianTest = { 1 }; -#define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1) - -#define COUNTOF(x) (sizeof((x))/sizeof((x)[0])) - - -#define DERIVE_FROM_TYPE(t) t t##_parent -#define STATIC_CAST(to, obj) (&(obj)->to##_parent) -#ifdef __GNUC__ -#define STATIC_UPCAST(to, from, obj) __extension__({ \ - static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \ - "Invalid upcast object from type"); \ - (to*)((char*)(obj) - offsetof(to, from##_parent)); \ -}) -#else -#define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent))) -#endif - -#define DECLARE_FORWARD(T1, T2, rettype, func) \ -rettype T1##_##func(T1 *obj) \ -{ return T2##_##func(STATIC_CAST(T2, obj)); } - -#define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \ -rettype T1##_##func(T1 *obj, argtype1 a) \ -{ return T2##_##func(STATIC_CAST(T2, obj), a); } - -#define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \ -rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \ -{ return T2##_##func(STATIC_CAST(T2, obj), a, b); } - -#define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ -rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \ -{ return T2##_##func(STATIC_CAST(T2, obj), a, b, c); } - - -#define GET_VTABLE1(T1) (&(T1##_vtable)) -#define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable)) - -#define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1)) -#define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2)) - -#define DECLARE_THUNK(T1, T2, rettype, func) \ -static rettype T1##_##T2##_##func(T2 *obj) \ -{ return T1##_##func(STATIC_UPCAST(T1, T2, obj)); } - -#define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \ -static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \ -{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); } - -#define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \ -static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \ -{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); } - -#define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \ -static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \ -{ return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); } - -#define DECLARE_DEFAULT_ALLOCATORS(T) \ -static void* T##_New(size_t size) { return malloc(size); } \ -static void T##_Delete(void *ptr) { free(ptr); } - -/* Helper to extract an argument list for VCALL. Not used directly. */ -#define EXTRACT_VCALL_ARGS(...) __VA_ARGS__)) - -/* Call a "virtual" method on an object, with arguments. */ -#define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS -/* Call a "virtual" method on an object, with no arguments. */ -#define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS - -#define DELETE_OBJ(obj) do { \ - if((obj) != NULL) \ - { \ - V0((obj),Destruct)(); \ - V0((obj),Delete)(); \ - } \ -} while(0) - - -#ifdef __cplusplus -extern "C" { -#endif - -struct Hrtf; - - -#define DEFAULT_OUTPUT_RATE (44100) -#define MIN_OUTPUT_RATE (8000) - - -/* Find the next power-of-2 for non-power-of-2 numbers. */ -inline ALuint NextPowerOf2(ALuint value) -{ - if(value > 0) - { - value--; - value |= value>>1; - value |= value>>2; - value |= value>>4; - value |= value>>8; - value |= value>>16; - } - return value+1; -} - -/* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero - * mode. */ -inline ALint fastf2i(ALfloat f) -{ -#ifdef HAVE_LRINTF - return lrintf(f); -#elif defined(_MSC_VER) && defined(_M_IX86) - ALint i; - __asm fld f - __asm fistp i - return i; -#else - return (ALint)f; -#endif -} - -/* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero - * mode. */ -inline ALuint fastf2u(ALfloat f) -{ return fastf2i(f); } - - -enum DevProbe { - ALL_DEVICE_PROBE, - CAPTURE_DEVICE_PROBE -}; - -typedef struct { - ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*); - void (*ClosePlayback)(ALCdevice*); - ALCboolean (*ResetPlayback)(ALCdevice*); - ALCboolean (*StartPlayback)(ALCdevice*); - void (*StopPlayback)(ALCdevice*); - - ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*); - void (*CloseCapture)(ALCdevice*); - void (*StartCapture)(ALCdevice*); - void (*StopCapture)(ALCdevice*); - ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint); - ALCuint (*AvailableSamples)(ALCdevice*); - - ALint64 (*GetLatency)(ALCdevice*); -} BackendFuncs; - -ALCboolean alc_solaris_init(BackendFuncs *func_list); -void alc_solaris_deinit(void); -void alc_solaris_probe(enum DevProbe type); -ALCboolean alc_sndio_init(BackendFuncs *func_list); -void alc_sndio_deinit(void); -void alc_sndio_probe(enum DevProbe type); -ALCboolean alcWinMMInit(BackendFuncs *FuncList); -void alcWinMMDeinit(void); -void alcWinMMProbe(enum DevProbe type); -ALCboolean alc_pa_init(BackendFuncs *func_list); -void alc_pa_deinit(void); -void alc_pa_probe(enum DevProbe type); -ALCboolean alc_wave_init(BackendFuncs *func_list); -void alc_wave_deinit(void); -void alc_wave_probe(enum DevProbe type); -ALCboolean alc_ca_init(BackendFuncs *func_list); -void alc_ca_deinit(void); -void alc_ca_probe(enum DevProbe type); -ALCboolean alc_opensl_init(BackendFuncs *func_list); -void alc_opensl_deinit(void); -void alc_opensl_probe(enum DevProbe type); -ALCboolean alc_qsa_init(BackendFuncs *func_list); -void alc_qsa_deinit(void); -void alc_qsa_probe(enum DevProbe type); - -struct ALCbackend; - - -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, - DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT, - DevFmtShort = ALC_SHORT_SOFT, - DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT, - DevFmtInt = ALC_INT_SOFT, - DevFmtUInt = ALC_UNSIGNED_INT_SOFT, - DevFmtFloat = ALC_FLOAT_SOFT, - - DevFmtTypeDefault = DevFmtFloat -}; -enum DevFmtChannels { - DevFmtMono = ALC_MONO_SOFT, - DevFmtStereo = ALC_STEREO_SOFT, - DevFmtQuad = ALC_QUAD_SOFT, - DevFmtX51 = ALC_5POINT1_SOFT, - DevFmtX61 = ALC_6POINT1_SOFT, - DevFmtX71 = ALC_7POINT1_SOFT, - - /* Similar to 5.1, except using the side channels instead of back */ - DevFmtX51Side = 0x80000000, - - DevFmtChannelsDefault = DevFmtStereo -}; - -ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST; -ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST; -inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type) -{ - return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type); -} - - -extern const struct EffectList { - const char *name; - int type; - const char *ename; - ALenum val; -} EffectList[]; - - -enum DeviceType { - Playback, - Capture, - 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. - */ -#define BUFFERSIZE (2048u) - - -struct ALCdevice_struct -{ - RefCount ref; - - ALCboolean Connected; - enum DeviceType Type; - - ALuint Frequency; - ALuint UpdateSize; - ALuint NumUpdates; - enum DevFmtChannels FmtChans; - enum DevFmtType FmtType; - - al_string DeviceName; - - ATOMIC(ALCenum) LastError; - - // Maximum number of sources that can be created - ALuint MaxNoOfSources; - // Maximum number of slots that can be created - ALuint AuxiliaryEffectSlotMax; - - ALCuint NumMonoSources; - ALCuint NumStereoSources; - ALuint NumAuxSends; - - // Map of Buffers for this device - UIntMap BufferMap; - - // Map of Effects for this device - UIntMap EffectMap; - - // Map of Filters for this device - UIntMap FilterMap; - - // Map of Soundfonts for this device - UIntMap SfontMap; - - // Map of Presets for this device - UIntMap PresetMap; - - // Map of Fontsounds for this device - UIntMap FontsoundMap; - - /* Default soundfont (accessible as ID 0) */ - struct ALsoundfont *DefaultSfont; - - /* MIDI synth engine */ - struct MidiSynth *Synth; - - /* HRTF filter tables */ - const struct Hrtf *Hrtf; - - // Stereo-to-binaural filter - struct bs2b *Bs2b; - ALCint Bs2bLevel; - - // Device flags - ALuint Flags; - - ALuint ChannelOffsets[MaxChannels]; - - enum Channel Speaker2Chan[MaxChannels]; - ALfloat SpeakerAngle[MaxChannels]; - ALuint NumChan; - - ALuint64 ClockBase; - ALuint SamplesDone; - - /* Temp storage used for each source when mixing. */ - alignas(16) ALfloat SourceData[BUFFERSIZE]; - alignas(16) ALfloat ResampledData[BUFFERSIZE]; - alignas(16) ALfloat FilteredData[BUFFERSIZE]; - - // Dry path buffer mix - alignas(16) ALfloat DryBuffer[MaxChannels][BUFFERSIZE]; - - /* Running count of the mixer invocations, in 31.1 fixed point. This - * actually increments *twice* when mixing, first at the start and then at - * the end, so the bottom bit indicates if the device is currently mixing - * and the upper bits indicates how many mixes have been done. - */ - RefCount MixCount; - - /* Default effect slot */ - struct ALeffectslot *DefaultSlot; - - // Contexts created on this device - ATOMIC(ALCcontext*) ContextList; - - struct ALCbackend *Backend; - - void *ExtraData; // For the backend's use - - ALCdevice *volatile next; - - /* Memory space used by the default slot (Playback devices only) */ - alignas(16) ALCbyte _slot_mem[]; -}; - -// Frequency was requested by the app or config file -#define DEVICE_FREQUENCY_REQUEST (1<<1) -// Channel configuration was requested by the config file -#define DEVICE_CHANNELS_REQUEST (1<<2) -// Sample type was requested by the config file -#define DEVICE_SAMPLE_TYPE_REQUEST (1<<3) -// HRTF was requested by the app -#define DEVICE_HRTF_REQUEST (1<<4) - -// Stereo sources cover 120-degree angles around +/-90 -#define DEVICE_WIDE_STEREO (1<<16) - -// Specifies if the DSP is paused at user request -#define DEVICE_PAUSED (1<<30) - -// Specifies if the device is currently running -#define DEVICE_RUNNING (1<<31) - -/* Invalid channel offset */ -#define INVALID_OFFSET (~0u) - - -/* Nanosecond resolution for the device clock time. */ -#define DEVICE_CLOCK_RES U64(1000000000) - - -/* Must be less than 15 characters (16 including terminating null) for - * compatibility with pthread_setname_np limitations. */ -#define MIXER_THREAD_NAME "alsoft-mixer" - - -struct ALCcontext_struct -{ - RefCount ref; - - struct ALlistener *Listener; - - UIntMap SourceMap; - UIntMap EffectSlotMap; - - ATOMIC(ALenum) LastError; - - ATOMIC(ALenum) UpdateSources; - - volatile enum DistanceModel DistanceModel; - volatile ALboolean SourceDistanceModel; - - volatile ALfloat DopplerFactor; - volatile ALfloat DopplerVelocity; - volatile ALfloat SpeedOfSound; - volatile ALenum DeferUpdates; - - struct ALactivesource **ActiveSources; - ALsizei ActiveSourceCount; - ALsizei MaxActiveSources; - - VECTOR(struct ALeffectslot*) ActiveAuxSlots; - - ALCdevice *Device; - const ALCchar *ExtensionList; - - ALCcontext *volatile next; - - /* Memory space used by the listener */ - alignas(16) ALCbyte _listener_mem[]; -}; - -ALCcontext *GetContextRef(void); - -void ALCcontext_IncRef(ALCcontext *context); -void ALCcontext_DecRef(ALCcontext *context); - -void AppendAllDevicesList(const ALCchar *name); -void AppendCaptureDeviceList(const ALCchar *name); - -ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device); - -void ALCdevice_Lock(ALCdevice *device); -void ALCdevice_Unlock(ALCdevice *device); -ALint64 ALCdevice_GetLatency(ALCdevice *device); - -inline void LockContext(ALCcontext *context) -{ ALCdevice_Lock(context->Device); } - -inline void UnlockContext(ALCcontext *context) -{ 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 { -#ifdef HAVE_FENV_H - DERIVE_FROM_TYPE(fenv_t); -#else - int state; -#endif -#ifdef HAVE_SSE - int sse_state; -#endif -} FPUCtl; -void SetMixerFPUMode(FPUCtl *ctl); -void RestoreFPUMode(const FPUCtl *ctl); - - -typedef struct RingBuffer RingBuffer; -RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length); -void DestroyRingBuffer(RingBuffer *ring); -ALsizei RingBufferSize(RingBuffer *ring); -void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len); -void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len); - -void ReadALConfig(void); -void FreeALConfig(void); -int ConfigValueExists(const char *blockName, const char *keyName); -const char *GetConfigValue(const char *blockName, const char *keyName, const char *def); -int GetConfigValueBool(const char *blockName, const char *keyName, int def); -int ConfigValueStr(const char *blockName, const char *keyName, const char **ret); -int ConfigValueInt(const char *blockName, const char *keyName, int *ret); -int ConfigValueUInt(const char *blockName, const char *keyName, unsigned int *ret); -int ConfigValueFloat(const char *blockName, const char *keyName, float *ret); - -void SetRTPriority(void); - -void SetDefaultChannelOrder(ALCdevice *device); -void SetDefaultWFXChannelOrder(ALCdevice *device); - -const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST; -const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST; - - -extern FILE *LogFile; - -#if defined(__GNUC__) && !defined(IN_IDE_PARSER) -#define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__) -#else -void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4); -#define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__) -#endif - -enum LogLevel { - NoLog, - LogError, - LogWarning, - LogTrace, - LogRef -}; -extern enum LogLevel LogLevel; - -#define TRACEREF(...) do { \ - if(LogLevel >= LogRef) \ - AL_PRINT("(--)", __VA_ARGS__); \ -} while(0) - -#define TRACE(...) do { \ - if(LogLevel >= LogTrace) \ - AL_PRINT("(II)", __VA_ARGS__); \ -} while(0) - -#define WARN(...) do { \ - if(LogLevel >= LogWarning) \ - AL_PRINT("(WW)", __VA_ARGS__); \ -} while(0) - -#define ERR(...) do { \ - if(LogLevel >= LogError) \ - AL_PRINT("(EE)", __VA_ARGS__); \ -} while(0) - - -extern ALint RTPrioLevel; - - -extern ALuint CPUCapFlags; -enum { - CPU_CAP_SSE = 1<<0, - CPU_CAP_SSE2 = 1<<1, - CPU_CAP_SSE4_1 = 1<<2, - CPU_CAP_NEON = 1<<3, -}; - -void FillCPUCaps(ALuint capfilter); - -FILE *OpenDataFile(const char *fname, const char *subdir); - -/* Small hack to use a pointer-to-array type as a normal argument type. - * Shouldn't be used directly. */ -typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE]; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMidi.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMidi.h deleted file mode 100644 index 9d9fa6c4..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alMidi.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef ALMIDI_H -#define ALMIDI_H - -#include "alMain.h" -#include "atomic.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ALsfmodulator { - struct { - ALenum Input; - ALenum Type; - ALenum Form; - } Source[2]; - ALint Amount; - ALenum TransformOp; - ALenum Dest; -} ALsfmodulator; - -typedef struct ALenvelope { - ALint DelayTime; - ALint AttackTime; - ALint HoldTime; - ALint DecayTime; - ALint SustainAttn; - ALint ReleaseTime; - ALint KeyToHoldTime; - ALint KeyToDecayTime; -} ALenvelope; - - -typedef struct ALfontsound { - RefCount ref; - - struct ALbuffer *Buffer; - - ALint MinKey, MaxKey; - ALint MinVelocity, MaxVelocity; - - ALint ModLfoToPitch; - ALint VibratoLfoToPitch; - ALint ModEnvToPitch; - - ALint FilterCutoff; - ALint FilterQ; - ALint ModLfoToFilterCutoff; - ALint ModEnvToFilterCutoff; - ALint ModLfoToVolume; - - ALint ChorusSend; - ALint ReverbSend; - - ALint Pan; - - struct { - ALint Delay; - ALint Frequency; - } ModLfo; - struct { - ALint Delay; - ALint Frequency; - } VibratoLfo; - - ALenvelope ModEnv; - ALenvelope VolEnv; - - ALint Attenuation; - - ALint CoarseTuning; - ALint FineTuning; - - ALenum LoopMode; - - ALint TuningScale; - - ALint ExclusiveClass; - - ALuint Start; - ALuint End; - ALuint LoopStart; - ALuint LoopEnd; - ALuint SampleRate; - ALubyte PitchKey; - ALbyte PitchCorrection; - ALenum SampleType; - struct ALfontsound *Link; - - /* NOTE: Each map entry contains *four* (4) ALsfmodulator objects. */ - UIntMap ModulatorMap; - - ALuint id; -} ALfontsound; - -void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value); -void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value); - -ALfontsound *NewFontsound(ALCcontext *context); -void DeleteFontsound(ALCdevice *device, ALfontsound *sound); - -inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id) -{ return (struct ALfontsound*)LookupUIntMapKey(&device->FontsoundMap, id); } -inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id) -{ return (struct ALfontsound*)RemoveUIntMapKey(&device->FontsoundMap, id); } - -void ReleaseALFontsounds(ALCdevice *device); - - -typedef struct ALsfpreset { - RefCount ref; - - ALint Preset; /* a.k.a. MIDI program number */ - ALint Bank; /* MIDI bank 0...127, or percussion (bank 128) */ - - ALfontsound **Sounds; - ALsizei NumSounds; - - ALuint id; -} ALsfpreset; - -ALsfpreset *NewPreset(ALCcontext *context); -void DeletePreset(ALCdevice *device, ALsfpreset *preset); - -inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id) -{ return (struct ALsfpreset*)LookupUIntMapKey(&device->PresetMap, id); } -inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id) -{ return (struct ALsfpreset*)RemoveUIntMapKey(&device->PresetMap, id); } - -void ReleaseALPresets(ALCdevice *device); - - -typedef struct ALsoundfont { - RefCount ref; - - ALsfpreset **Presets; - ALsizei NumPresets; - - RWLock Lock; - - ALuint id; -} ALsoundfont; - -ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context); -void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device); - -inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id) -{ return (struct ALsoundfont*)LookupUIntMapKey(&device->SfontMap, id); } -inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id) -{ return (struct ALsoundfont*)RemoveUIntMapKey(&device->SfontMap, id); } - -void ReleaseALSoundfonts(ALCdevice *device); - - -inline ALboolean IsValidCtrlInput(int cc) -{ - /* These correspond to MIDI functions, not real controller values. */ - if(cc == 0 || cc == 6 || cc == 32 || cc == 38 || (cc >= 98 && cc <= 101) || cc >= 120) - return AL_FALSE; - /* These are the LSB components of CC0...CC31, which are automatically used when - * reading the MSB controller value. */ - if(cc >= 32 && cc <= 63) - return AL_FALSE; - /* All the rest are okay! */ - return AL_TRUE; -} - -#ifdef __cplusplus -} -#endif - -#endif /* ALMIDI_H */ diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alSource.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alSource.h deleted file mode 100644 index 8d74fc54..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alSource.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef _AL_SOURCE_H_ -#define _AL_SOURCE_H_ - -#define MAX_SENDS 4 - -#include "alMain.h" -#include "alu.h" -#include "hrtf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern enum Resampler DefaultResampler; - -extern const ALsizei ResamplerPadding[ResamplerMax]; -extern const ALsizei ResamplerPrePadding[ResamplerMax]; - - -typedef struct ALbufferlistitem { - struct ALbuffer *buffer; - struct ALbufferlistitem *volatile next; - struct ALbufferlistitem *volatile prev; -} ALbufferlistitem; - - -typedef struct ALactivesource { - struct ALsource *Source; - - /** Method to update mixing parameters. */ - ALvoid (*Update)(struct ALactivesource *self, const ALCcontext *context); - - /** Current target parameters used for mixing. */ - ALint Step; - - ALboolean IsHrtf; - - ALuint Offset; /* Number of output samples mixed since starting. */ - - DirectParams Direct; - SendParams Send[MAX_SENDS]; -} ALactivesource; - - -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; - volatile ALboolean WetGainHFAuto; - volatile ALfloat OuterGainHF; - - volatile ALfloat AirAbsorptionFactor; - volatile ALfloat RoomRolloffFactor; - volatile ALfloat DopplerFactor; - - volatile ALfloat Radius; - - enum Resampler Resampler; - - /** - * 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. */ - ATOMIC(ALbufferlistitem*) queue; - ATOMIC(ALbufferlistitem*) current_buffer; - RWLock queue_lock; - - /** Current buffer sample info. */ - ALuint NumChannels; - ALuint SampleSize; - - /** Direct filter and auxiliary send info. */ - struct { - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Direct; - struct { - struct ALeffectslot *Slot; - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Send[MAX_SENDS]; - - /** Source needs to update its mixing parameters. */ - ATOMIC(ALenum) NeedsUpdate; - - /** Self ID */ - ALuint id; -} ALsource; - -inline struct ALsource *LookupSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)LookupUIntMapKey(&context->SourceMap, id); } -inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id) -{ return (struct ALsource*)RemoveUIntMapKey(&context->SourceMap, id); } - -ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state); -ALboolean ApplyOffset(ALsource *Source); - -ALvoid ReleaseALSources(ALCcontext *Context); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alu.h b/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alu.h deleted file mode 100644 index 7727c666..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/Include/alu.h +++ /dev/null @@ -1,236 +0,0 @@ -#ifndef _ALU_H_ -#define _ALU_H_ - -#include -#include -#ifdef HAVE_FLOAT_H -#include -#endif -#ifdef HAVE_IEEEFP_H -#include -#endif - -#include "alMain.h" -#include "alBuffer.h" -#include "alFilter.h" - -#include "hrtf.h" -#include "align.h" - - -#define F_PI (3.14159265358979323846f) -#define F_PI_2 (1.57079632679489661923f) -#define F_2PI (6.28318530717958647692f) - -#ifndef FLT_EPSILON -#define FLT_EPSILON (1.19209290e-07f) -#endif - -#define DEG2RAD(x) ((ALfloat)(x) * (F_PI/180.0f)) -#define RAD2DEG(x) ((ALfloat)(x) * (180.0f/F_PI)) - - -#define SRC_HISTORY_BITS (6) -#define SRC_HISTORY_LENGTH (1< b) ? b : a); } -inline ALfloat maxf(ALfloat a, ALfloat b) -{ return ((a > b) ? a : b); } -inline ALfloat clampf(ALfloat val, ALfloat min, ALfloat max) -{ return minf(max, maxf(min, val)); } - -inline ALdouble mind(ALdouble a, ALdouble b) -{ return ((a > b) ? b : a); } -inline ALdouble maxd(ALdouble a, ALdouble b) -{ return ((a > b) ? a : b); } -inline ALdouble clampd(ALdouble val, ALdouble min, ALdouble max) -{ return mind(max, maxd(min, val)); } - -inline ALuint minu(ALuint a, ALuint b) -{ return ((a > b) ? b : a); } -inline ALuint maxu(ALuint a, ALuint b) -{ return ((a > b) ? a : b); } -inline ALuint clampu(ALuint val, ALuint min, ALuint max) -{ return minu(max, maxu(min, val)); } - -inline ALint mini(ALint a, ALint b) -{ return ((a > b) ? b : a); } -inline ALint maxi(ALint a, ALint b) -{ return ((a > b) ? a : b); } -inline ALint clampi(ALint val, ALint min, ALint max) -{ return mini(max, maxi(min, val)); } - -inline ALint64 mini64(ALint64 a, ALint64 b) -{ return ((a > b) ? b : a); } -inline ALint64 maxi64(ALint64 a, ALint64 b) -{ return ((a > b) ? a : b); } -inline ALint64 clampi64(ALint64 val, ALint64 min, ALint64 max) -{ return mini64(max, maxi64(min, val)); } - -inline ALuint64 minu64(ALuint64 a, ALuint64 b) -{ return ((a > b) ? b : a); } -inline ALuint64 maxu64(ALuint64 a, ALuint64 b) -{ return ((a > b) ? a : b); } -inline ALuint64 clampu64(ALuint64 val, ALuint64 min, ALuint64 max) -{ return minu64(max, maxu64(min, val)); } - - -inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) -{ - return val1 + (val2-val1)*mu; -} -inline ALfloat cubic(ALfloat val0, ALfloat val1, ALfloat val2, ALfloat val3, ALfloat mu) -{ - ALfloat mu2 = mu*mu; - ALfloat a0 = -0.5f*val0 + 1.5f*val1 + -1.5f*val2 + 0.5f*val3; - ALfloat a1 = val0 + -2.5f*val1 + 2.0f*val2 + -0.5f*val3; - ALfloat a2 = -0.5f*val0 + 0.5f*val2; - ALfloat a3 = val1; - - return a0*mu*mu2 + a1*mu2 + a2*mu + a3; -} - - -ALvoid aluInitPanning(ALCdevice *Device); - -/** - * ComputeAngleGains - * - * Sets channel gains based on a given source's angle and its half-width. The - * angle and hwidth parameters are in radians. - */ -void ComputeAngleGains(const ALCdevice *device, ALfloat angle, ALfloat hwidth, ALfloat ingain, ALfloat gains[MaxChannels]); - -/** - * SetGains - * - * Helper to set the appropriate channels to the specified gain. - */ -inline void SetGains(const ALCdevice *device, ALfloat ingain, ALfloat gains[MaxChannels]) -{ - ComputeAngleGains(device, 0.0f, F_PI, ingain, gains); -} - - -ALvoid CalcSourceParams(struct ALactivesource *src, const ALCcontext *ALContext); -ALvoid CalcNonAttnSourceParams(struct ALactivesource *src, const ALCcontext *ALContext); - -ALvoid MixSource(struct ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo); - -ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size); -/* Caller must lock the device. */ -ALvoid aluHandleDisconnect(ALCdevice *device); - -extern ALfloat ConeScale; -extern ALfloat ZScale; - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/alFontsound.c b/love/src/jni/openal-soft-1.17.0/OpenAL32/alFontsound.c deleted file mode 100644 index 3a8f1460..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/alFontsound.c +++ /dev/null @@ -1,1008 +0,0 @@ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alMidi.h" -#include "alError.h" -#include "alThunk.h" -#include "alBuffer.h" - -#include "midi/base.h" - - -extern inline struct ALfontsound *LookupFontsound(ALCdevice *device, ALuint id); -extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id); - - -static void ALfontsound_Construct(ALfontsound *self); -static void ALfontsound_Destruct(ALfontsound *self); -void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value); -static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage); -void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value); -static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values); - -static inline struct ALsfmodulator *LookupModulator(ALfontsound *sound, ALuint id) -{ - ALsfmodulator *mod = LookupUIntMapKey(&sound->ModulatorMap, id>>2); - if(mod) mod += id&3; - return mod; -} - - -AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids) -{ - ALCcontext *context; - ALsizei cur = 0; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - for(cur = 0;cur < n;cur++) - { - ALfontsound *sound = NewFontsound(context); - if(!sound) - { - alDeleteFontsoundsSOFT(cur, ids); - break; - } - - ids[cur] = sound->id; - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alDeleteFontsoundsSOFT(ALsizei n, const ALuint *ids) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *inst; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - for(i = 0;i < n;i++) - { - /* Check for valid ID */ - if((inst=LookupFontsound(device, ids[i])) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&inst->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - for(i = 0;i < n;i++) - { - if((inst=LookupFontsound(device, ids[i])) != NULL) - DeleteFontsound(device, inst); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALboolean AL_APIENTRY alIsFontsoundSOFT(ALuint id) -{ - ALCcontext *context; - ALboolean ret; - - context = GetContextRef(); - if(!context) return AL_FALSE; - - ret = LookupFontsound(context->Device, id) ? AL_TRUE : AL_FALSE; - - ALCcontext_DecRef(context); - - return ret; -} - -AL_API void AL_APIENTRY alFontsoundiSOFT(ALuint id, ALenum param, ALint value) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *sound; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&sound->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - - ALfontsound_setPropi(sound, context, param, value); - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alFontsound2iSOFT(ALuint id, ALenum param, ALint value1, ALint value2) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *sound; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&sound->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - switch(param) - { - case AL_KEY_RANGE_SOFT: - if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - sound->MinKey = value1; - sound->MaxKey = value2; - break; - - case AL_VELOCITY_RANGE_SOFT: - if(!(value1 >= 0 && value1 <= 127 && value2 >= 0 && value2 <= 127 && value2 >= value1)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - sound->MinVelocity = value1; - sound->MaxVelocity = value2; - break; - - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alFontsoundivSOFT(ALuint id, ALenum param, const ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *sound; - - switch(param) - { - case AL_KEY_RANGE_SOFT: - case AL_VELOCITY_RANGE_SOFT: - alFontsound2iSOFT(id, param, values[0], values[1]); - return; - - case AL_MOD_LFO_TO_PITCH_SOFT: - case AL_VIBRATO_LFO_TO_PITCH_SOFT: - case AL_MOD_ENV_TO_PITCH_SOFT: - case AL_FILTER_CUTOFF_SOFT: - case AL_FILTER_RESONANCE_SOFT: - case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: - case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: - case AL_MOD_LFO_TO_VOLUME_SOFT: - case AL_CHORUS_SEND_SOFT: - case AL_REVERB_SEND_SOFT: - case AL_PAN_SOFT: - case AL_MOD_LFO_DELAY_SOFT: - case AL_MOD_LFO_FREQUENCY_SOFT: - case AL_VIBRATO_LFO_DELAY_SOFT: - case AL_VIBRATO_LFO_FREQUENCY_SOFT: - case AL_MOD_ENV_DELAYTIME_SOFT: - case AL_MOD_ENV_ATTACKTIME_SOFT: - case AL_MOD_ENV_HOLDTIME_SOFT: - case AL_MOD_ENV_DECAYTIME_SOFT: - case AL_MOD_ENV_SUSTAINVOLUME_SOFT: - case AL_MOD_ENV_RELEASETIME_SOFT: - case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: - case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: - case AL_VOLUME_ENV_DELAYTIME_SOFT: - case AL_VOLUME_ENV_ATTACKTIME_SOFT: - case AL_VOLUME_ENV_HOLDTIME_SOFT: - case AL_VOLUME_ENV_DECAYTIME_SOFT: - case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: - case AL_VOLUME_ENV_RELEASETIME_SOFT: - case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: - case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: - case AL_ATTENUATION_SOFT: - case AL_TUNING_COARSE_SOFT: - case AL_TUNING_FINE_SOFT: - case AL_LOOP_MODE_SOFT: - case AL_TUNING_SCALE_SOFT: - case AL_EXCLUSIVE_CLASS_SOFT: - case AL_SAMPLE_START_SOFT: - case AL_SAMPLE_END_SOFT: - case AL_SAMPLE_LOOP_START_SOFT: - case AL_SAMPLE_LOOP_END_SOFT: - case AL_SAMPLE_RATE_SOFT: - case AL_BASE_KEY_SOFT: - case AL_KEY_CORRECTION_SOFT: - case AL_SAMPLE_TYPE_SOFT: - case AL_FONTSOUND_LINK_SOFT: - alFontsoundiSOFT(id, param, values[0]); - return; - } - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&sound->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - switch(param) - { - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alGetFontsoundivSOFT(ALuint id, ALenum param, ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - const ALfontsound *sound; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - switch(param) - { - case AL_BUFFER: - values[0] = (sound->Buffer ? sound->Buffer->id : 0); - break; - - case AL_MOD_LFO_TO_PITCH_SOFT: - values[0] = sound->ModLfoToPitch; - break; - - case AL_VIBRATO_LFO_TO_PITCH_SOFT: - values[0] = sound->VibratoLfoToPitch; - break; - - case AL_MOD_ENV_TO_PITCH_SOFT: - values[0] = sound->ModEnvToPitch; - break; - - case AL_FILTER_CUTOFF_SOFT: - values[0] = sound->FilterCutoff; - break; - - case AL_FILTER_RESONANCE_SOFT: - values[0] = sound->FilterQ; - break; - - case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: - values[0] = sound->ModLfoToFilterCutoff; - break; - - case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: - values[0] = sound->ModEnvToFilterCutoff; - break; - - case AL_MOD_LFO_TO_VOLUME_SOFT: - values[0] = sound->ModLfoToVolume; - break; - - case AL_CHORUS_SEND_SOFT: - values[0] = sound->ChorusSend; - break; - - case AL_REVERB_SEND_SOFT: - values[0] = sound->ReverbSend; - break; - - case AL_PAN_SOFT: - values[0] = sound->Pan; - break; - - case AL_MOD_LFO_DELAY_SOFT: - values[0] = sound->ModLfo.Delay; - break; - case AL_MOD_LFO_FREQUENCY_SOFT: - values[0] = sound->ModLfo.Frequency; - break; - - case AL_VIBRATO_LFO_DELAY_SOFT: - values[0] = sound->VibratoLfo.Delay; - break; - case AL_VIBRATO_LFO_FREQUENCY_SOFT: - values[0] = sound->VibratoLfo.Frequency; - break; - - case AL_MOD_ENV_DELAYTIME_SOFT: - values[0] = sound->ModEnv.DelayTime; - break; - case AL_MOD_ENV_ATTACKTIME_SOFT: - values[0] = sound->ModEnv.AttackTime; - break; - case AL_MOD_ENV_HOLDTIME_SOFT: - values[0] = sound->ModEnv.HoldTime; - break; - case AL_MOD_ENV_DECAYTIME_SOFT: - values[0] = sound->ModEnv.DecayTime; - break; - case AL_MOD_ENV_SUSTAINVOLUME_SOFT: - values[0] = sound->ModEnv.SustainAttn; - break; - case AL_MOD_ENV_RELEASETIME_SOFT: - values[0] = sound->ModEnv.ReleaseTime; - break; - case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: - values[0] = sound->ModEnv.KeyToHoldTime; - break; - case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: - values[0] = sound->ModEnv.KeyToDecayTime; - break; - - case AL_VOLUME_ENV_DELAYTIME_SOFT: - values[0] = sound->VolEnv.DelayTime; - break; - case AL_VOLUME_ENV_ATTACKTIME_SOFT: - values[0] = sound->VolEnv.AttackTime; - break; - case AL_VOLUME_ENV_HOLDTIME_SOFT: - values[0] = sound->VolEnv.HoldTime; - break; - case AL_VOLUME_ENV_DECAYTIME_SOFT: - values[0] = sound->VolEnv.DecayTime; - break; - case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: - values[0] = sound->VolEnv.SustainAttn; - break; - case AL_VOLUME_ENV_RELEASETIME_SOFT: - values[0] = sound->VolEnv.ReleaseTime; - break; - case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: - values[0] = sound->VolEnv.KeyToHoldTime; - break; - case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: - values[0] = sound->VolEnv.KeyToDecayTime; - break; - - case AL_KEY_RANGE_SOFT: - values[0] = sound->MinKey; - values[1] = sound->MaxKey; - break; - - case AL_VELOCITY_RANGE_SOFT: - values[0] = sound->MinVelocity; - values[1] = sound->MaxVelocity; - break; - - case AL_ATTENUATION_SOFT: - values[0] = sound->Attenuation; - break; - - case AL_TUNING_COARSE_SOFT: - values[0] = sound->CoarseTuning; - break; - case AL_TUNING_FINE_SOFT: - values[0] = sound->FineTuning; - break; - - case AL_LOOP_MODE_SOFT: - values[0] = sound->LoopMode; - break; - - case AL_TUNING_SCALE_SOFT: - values[0] = sound->TuningScale; - break; - - case AL_EXCLUSIVE_CLASS_SOFT: - values[0] = sound->ExclusiveClass; - break; - - case AL_SAMPLE_START_SOFT: - values[0] = sound->Start; - break; - - case AL_SAMPLE_END_SOFT: - values[0] = sound->End; - break; - - case AL_SAMPLE_LOOP_START_SOFT: - values[0] = sound->LoopStart; - break; - - case AL_SAMPLE_LOOP_END_SOFT: - values[0] = sound->LoopEnd; - break; - - case AL_SAMPLE_RATE_SOFT: - values[0] = sound->SampleRate; - break; - - case AL_BASE_KEY_SOFT: - values[0] = sound->PitchKey; - break; - - case AL_KEY_CORRECTION_SOFT: - values[0] = sound->PitchCorrection; - break; - - case AL_SAMPLE_TYPE_SOFT: - values[0] = sound->SampleType; - break; - - case AL_FONTSOUND_LINK_SOFT: - values[0] = (sound->Link ? sound->Link->id : 0); - break; - - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alFontsoundModulatoriSOFT(ALuint id, ALsizei stage, ALenum param, ALint value) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *sound; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - ALfontsound_setModStagei(sound, context, stage, param, value); - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alGetFontsoundModulatorivSOFT(ALuint id, ALsizei stage, ALenum param, ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - ALfontsound *sound; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(sound=LookupFontsound(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - ALfontsound_getModStagei(sound, context, stage, param, values); - -done: - ALCcontext_DecRef(context); -} - - -ALfontsound *NewFontsound(ALCcontext *context) -{ - ALCdevice *device = context->Device; - ALfontsound *sound; - ALenum err; - - sound = calloc(1, sizeof(*sound)); - if(!sound) - SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); - ALfontsound_Construct(sound); - - err = NewThunkEntry(&sound->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->FontsoundMap, sound->id, sound); - if(err != AL_NO_ERROR) - { - ALfontsound_Destruct(sound); - memset(sound, 0, sizeof(*sound)); - free(sound); - - SET_ERROR_AND_RETURN_VALUE(context, err, NULL); - } - - return sound; -} - -void DeleteFontsound(ALCdevice *device, ALfontsound *sound) -{ - RemoveFontsound(device, sound->id); - - ALfontsound_Destruct(sound); - - memset(sound, 0, sizeof(*sound)); - free(sound); -} - - -static void ALfontsound_Construct(ALfontsound *self) -{ - InitRef(&self->ref, 0); - - self->Buffer = NULL; - - self->MinKey = 0; - self->MaxKey = 127; - self->MinVelocity = 0; - self->MaxVelocity = 127; - - self->ModLfoToPitch = 0; - self->VibratoLfoToPitch = 0; - self->ModEnvToPitch = 0; - - self->FilterCutoff = 13500; - self->FilterQ = 0; - self->ModLfoToFilterCutoff = 0; - self->ModEnvToFilterCutoff = 0; - self->ModLfoToVolume = 0; - - self->ChorusSend = 0; - self->ReverbSend = 0; - - self->Pan = 0; - - self->ModLfo.Delay = 0; - self->ModLfo.Frequency = 0; - - self->VibratoLfo.Delay = 0; - self->VibratoLfo.Frequency = 0; - - self->ModEnv.DelayTime = -12000; - self->ModEnv.AttackTime = -12000; - self->ModEnv.HoldTime = -12000; - self->ModEnv.DecayTime = -12000; - self->ModEnv.SustainAttn = 0; - self->ModEnv.ReleaseTime = -12000; - self->ModEnv.KeyToHoldTime = 0; - self->ModEnv.KeyToDecayTime = 0; - - self->VolEnv.DelayTime = -12000; - self->VolEnv.AttackTime = -12000; - self->VolEnv.HoldTime = -12000; - self->VolEnv.DecayTime = -12000; - self->VolEnv.SustainAttn = 0; - self->VolEnv.ReleaseTime = -12000; - self->VolEnv.KeyToHoldTime = 0; - self->VolEnv.KeyToDecayTime = 0; - - self->Attenuation = 0; - - self->CoarseTuning = 0; - self->FineTuning = 0; - - self->LoopMode = AL_NONE; - - self->TuningScale = 100; - - self->ExclusiveClass = 0; - - self->Start = 0; - self->End = 0; - self->LoopStart = 0; - self->LoopEnd = 0; - self->SampleRate = 0; - self->PitchKey = 0; - self->PitchCorrection = 0; - self->SampleType = AL_MONO_SOFT; - self->Link = NULL; - - InitUIntMap(&self->ModulatorMap, ~0); - - self->id = 0; -} - -static void ALfontsound_Destruct(ALfontsound *self) -{ - ALsizei i; - - FreeThunkEntry(self->id); - self->id = 0; - - if(self->Buffer) - DecrementRef(&self->Buffer->ref); - self->Buffer = NULL; - if(self->Link) - DecrementRef(&self->Link->ref); - self->Link = NULL; - - for(i = 0;i < self->ModulatorMap.size;i++) - { - free(self->ModulatorMap.array[i].value); - self->ModulatorMap.array[i].value = NULL; - } - ResetUIntMap(&self->ModulatorMap); -} - -void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param, ALint value) -{ - ALfontsound *link; - ALbuffer *buffer; - - switch(param) - { - case AL_BUFFER: - buffer = value ? LookupBuffer(context->Device, value) : NULL; - if(value && !buffer) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - else if(buffer) - { - /* Buffer must have a non-0 length, and must be mono. */ - if(buffer->SampleLen <= 0 || buffer->FmtChannels != FmtMono) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - } - - if(buffer) IncrementRef(&buffer->ref); - if((buffer=ExchangePtr((XchgPtr*)&self->Buffer, buffer)) != NULL) - DecrementRef(&buffer->ref); - break; - - case AL_MOD_LFO_TO_PITCH_SOFT: - self->ModLfoToPitch = value; - break; - - case AL_VIBRATO_LFO_TO_PITCH_SOFT: - self->VibratoLfoToPitch = value; - break; - - case AL_MOD_ENV_TO_PITCH_SOFT: - self->ModEnvToPitch = value; - break; - - case AL_FILTER_CUTOFF_SOFT: - self->FilterCutoff = value; - break; - - case AL_FILTER_RESONANCE_SOFT: - if(!(value >= 0)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->FilterQ = value; - break; - - case AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT: - self->ModLfoToFilterCutoff = value; - break; - - case AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT: - self->ModEnvToFilterCutoff = value; - break; - - case AL_MOD_LFO_TO_VOLUME_SOFT: - self->ModLfoToVolume = value; - break; - - case AL_CHORUS_SEND_SOFT: - if(!(value >= 0 && value <= 1000)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->ChorusSend = value; - break; - case AL_REVERB_SEND_SOFT: - if(!(value >= 0 && value <= 1000)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->ReverbSend = value; - break; - - case AL_PAN_SOFT: - self->Pan = value; - break; - - case AL_MOD_LFO_DELAY_SOFT: - self->ModLfo.Delay = value; - break; - case AL_MOD_LFO_FREQUENCY_SOFT: - self->ModLfo.Frequency = value; - break; - - case AL_VIBRATO_LFO_DELAY_SOFT: - self->VibratoLfo.Delay = value; - break; - case AL_VIBRATO_LFO_FREQUENCY_SOFT: - self->VibratoLfo.Frequency = value; - break; - - case AL_MOD_ENV_DELAYTIME_SOFT: - self->ModEnv.DelayTime = value; - break; - case AL_MOD_ENV_ATTACKTIME_SOFT: - self->ModEnv.AttackTime = value; - break; - case AL_MOD_ENV_HOLDTIME_SOFT: - self->ModEnv.HoldTime = value; - break; - case AL_MOD_ENV_DECAYTIME_SOFT: - self->ModEnv.DecayTime = value; - break; - case AL_MOD_ENV_SUSTAINVOLUME_SOFT: - self->ModEnv.SustainAttn = value; - break; - case AL_MOD_ENV_RELEASETIME_SOFT: - self->ModEnv.ReleaseTime = value; - break; - case AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT: - self->ModEnv.KeyToHoldTime = value; - break; - case AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT: - self->ModEnv.KeyToDecayTime = value; - break; - - case AL_VOLUME_ENV_DELAYTIME_SOFT: - self->VolEnv.DelayTime = value; - break; - case AL_VOLUME_ENV_ATTACKTIME_SOFT: - self->VolEnv.AttackTime = value; - break; - case AL_VOLUME_ENV_HOLDTIME_SOFT: - self->VolEnv.HoldTime = value; - break; - case AL_VOLUME_ENV_DECAYTIME_SOFT: - self->VolEnv.DecayTime = value; - break; - case AL_VOLUME_ENV_SUSTAINVOLUME_SOFT: - self->VolEnv.SustainAttn = value; - break; - case AL_VOLUME_ENV_RELEASETIME_SOFT: - self->VolEnv.ReleaseTime = value; - break; - case AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT: - self->VolEnv.KeyToHoldTime = value; - break; - case AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT: - self->VolEnv.KeyToDecayTime = value; - break; - - case AL_ATTENUATION_SOFT: - if(!(value >= 0)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->Attenuation = value; - break; - - case AL_TUNING_COARSE_SOFT: - self->CoarseTuning = value; - break; - case AL_TUNING_FINE_SOFT: - self->FineTuning = value; - break; - - case AL_LOOP_MODE_SOFT: - if(!(value == AL_NONE || value == AL_LOOP_CONTINUOUS_SOFT || - value == AL_LOOP_UNTIL_RELEASE_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->LoopMode = value; - break; - - case AL_TUNING_SCALE_SOFT: - self->TuningScale = value; - break; - - case AL_EXCLUSIVE_CLASS_SOFT: - self->ExclusiveClass = value; - break; - - case AL_SAMPLE_START_SOFT: - self->Start = value; - break; - - case AL_SAMPLE_END_SOFT: - self->End = value; - break; - - case AL_SAMPLE_LOOP_START_SOFT: - self->LoopStart = value; - break; - - case AL_SAMPLE_LOOP_END_SOFT: - self->LoopEnd = value; - break; - - case AL_SAMPLE_RATE_SOFT: - if(!(value > 0)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->SampleRate = value; - break; - - case AL_BASE_KEY_SOFT: - if(!((value >= 0 && value <= 127) || value == 255)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->PitchKey = value; - break; - - case AL_KEY_CORRECTION_SOFT: - if(!(value >= -99 && value <= 99)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->PitchCorrection = value; - break; - - case AL_SAMPLE_TYPE_SOFT: - if(!(value == AL_MONO_SOFT || value == AL_RIGHT_SOFT || value == AL_LEFT_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - self->SampleType = value; - break; - - case AL_FONTSOUND_LINK_SOFT: - link = value ? LookupFontsound(context->Device, value) : NULL; - if(value && !link) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - - if(link) IncrementRef(&link->ref); - if((link=ExchangePtr((XchgPtr*)&self->Link, link)) != NULL) - DecrementRef(&link->ref); - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} - -static ALsfmodulator *ALfontsound_getModStage(ALfontsound *self, ALsizei stage) -{ - ALsfmodulator *ret = LookupModulator(self, stage); - if(!ret) - { - static const ALsfmodulator moddef = { - { { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT }, - { AL_ONE_SOFT, AL_UNORM_SOFT, AL_LINEAR_SOFT } }, - 0, - AL_LINEAR_SOFT, - AL_NONE - }; - ret = malloc(sizeof(ALsfmodulator[4])); - ret[0] = moddef; - ret[1] = moddef; - ret[2] = moddef; - ret[3] = moddef; - InsertUIntMapEntry(&self->ModulatorMap, stage>>2, ret); - ret += stage&3; - } - return ret; -} - -void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value) -{ - ALint srcidx = 0; - - if(ReadRef(&self->ref) != 0) - SET_ERROR_AND_RETURN(context, AL_INVALID_OPERATION); - switch(param) - { - case AL_SOURCE1_INPUT_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_INPUT_SOFT: - if(!(value == AL_ONE_SOFT || value == AL_NOTEON_VELOCITY_SOFT || - value == AL_NOTEON_KEY_SOFT || value == AL_KEYPRESSURE_SOFT || - value == AL_CHANNELPRESSURE_SOFT || value == AL_PITCHBEND_SOFT || - value == AL_PITCHBEND_SENSITIVITY_SOFT || - IsValidCtrlInput(value))) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - ALfontsound_getModStage(self, stage)->Source[srcidx].Input = value; - break; - - case AL_SOURCE1_TYPE_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_TYPE_SOFT: - if(!(value == AL_UNORM_SOFT || value == AL_UNORM_REV_SOFT || - value == AL_SNORM_SOFT || value == AL_SNORM_REV_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - ALfontsound_getModStage(self, stage)->Source[srcidx].Type = value; - break; - - case AL_SOURCE1_FORM_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_FORM_SOFT: - if(!(value == AL_LINEAR_SOFT || value == AL_CONCAVE_SOFT || - value == AL_CONVEX_SOFT || value == AL_SWITCH_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - ALfontsound_getModStage(self, stage)->Source[srcidx].Form = value; - break; - - case AL_AMOUNT_SOFT: - ALfontsound_getModStage(self, stage)->Amount = value; - break; - - case AL_TRANSFORM_OP_SOFT: - if(!(value == AL_LINEAR_SOFT || value == AL_ABSOLUTE_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - ALfontsound_getModStage(self, stage)->TransformOp = value; - break; - - case AL_DESTINATION_SOFT: - if(!(value == AL_MOD_LFO_TO_PITCH_SOFT || value == AL_VIBRATO_LFO_TO_PITCH_SOFT || - value == AL_MOD_ENV_TO_PITCH_SOFT || value == AL_FILTER_CUTOFF_SOFT || - value == AL_FILTER_RESONANCE_SOFT || value == AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT || - value == AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT || value == AL_MOD_LFO_TO_VOLUME_SOFT || - value == AL_CHORUS_SEND_SOFT || value == AL_REVERB_SEND_SOFT || value == AL_PAN_SOFT || - value == AL_MOD_LFO_DELAY_SOFT || value == AL_MOD_LFO_FREQUENCY_SOFT || - value == AL_VIBRATO_LFO_DELAY_SOFT || value == AL_VIBRATO_LFO_FREQUENCY_SOFT || - value == AL_MOD_ENV_DELAYTIME_SOFT || value == AL_MOD_ENV_ATTACKTIME_SOFT || - value == AL_MOD_ENV_HOLDTIME_SOFT || value == AL_MOD_ENV_DECAYTIME_SOFT || - value == AL_MOD_ENV_SUSTAINVOLUME_SOFT || value == AL_MOD_ENV_RELEASETIME_SOFT || - value == AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT || - value == AL_VOLUME_ENV_DELAYTIME_SOFT || value == AL_VOLUME_ENV_ATTACKTIME_SOFT || - value == AL_VOLUME_ENV_HOLDTIME_SOFT || value == AL_VOLUME_ENV_DECAYTIME_SOFT || - value == AL_VOLUME_ENV_SUSTAINVOLUME_SOFT || value == AL_VOLUME_ENV_RELEASETIME_SOFT || - value == AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT || value == AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT || - value == AL_ATTENUATION_SOFT || value == AL_TUNING_COARSE_SOFT || - value == AL_TUNING_FINE_SOFT || value == AL_TUNING_SCALE_SOFT)) - SET_ERROR_AND_RETURN(context, AL_INVALID_VALUE); - ALfontsound_getModStage(self, stage)->Dest = value; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} - -static void ALfontsound_getModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint *values) -{ - ALsfmodulator *mod = LookupModulator(self, stage); - ALint srcidx = 0; - - switch(param) - { - case AL_SOURCE1_INPUT_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_INPUT_SOFT: - values[0] = mod ? mod->Source[srcidx].Input : AL_ONE_SOFT; - break; - - case AL_SOURCE1_TYPE_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_TYPE_SOFT: - values[0] = mod ? mod->Source[srcidx].Type : AL_UNORM_SOFT; - break; - - case AL_SOURCE1_FORM_SOFT: - srcidx++; - /* fall-through */ - case AL_SOURCE0_FORM_SOFT: - values[0] = mod ? mod->Source[srcidx].Form : AL_LINEAR_SOFT; - break; - - case AL_AMOUNT_SOFT: - values[0] = mod ? mod->Amount : 0; - break; - - case AL_TRANSFORM_OP_SOFT: - values[0] = mod ? mod->TransformOp : AL_LINEAR_SOFT; - break; - - case AL_DESTINATION_SOFT: - values[0] = mod ? mod->Dest : AL_NONE; - break; - - default: - SET_ERROR_AND_RETURN(context, AL_INVALID_ENUM); - } -} - - -/* ReleaseALFontsounds - * - * Called to destroy any fontsounds that still exist on the device - */ -void ReleaseALFontsounds(ALCdevice *device) -{ - ALsizei i; - for(i = 0;i < device->FontsoundMap.size;i++) - { - ALfontsound *temp = device->FontsoundMap.array[i].value; - device->FontsoundMap.array[i].value = NULL; - - ALfontsound_Destruct(temp); - - memset(temp, 0, sizeof(*temp)); - free(temp); - } -} diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/alMidi.c b/love/src/jni/openal-soft-1.17.0/OpenAL32/alMidi.c deleted file mode 100644 index 015b1915..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/alMidi.c +++ /dev/null @@ -1,217 +0,0 @@ - -#include "config.h" - -#include -#include -#include -#include - -#include "alMain.h" -#include "alMidi.h" -#include "alError.h" -#include "alThunk.h" -#include "evtqueue.h" -#include "rwlock.h" -#include "alu.h" - -#include "midi/base.h" - - -MidiSynth *SynthCreate(ALCdevice *device) -{ - MidiSynth *synth = NULL; - if(!synth) synth = SSynth_create(device); - if(!synth) synth = FSynth_create(device); - if(!synth) synth = DSynth_create(device); - return synth; -} - - -AL_API void AL_APIENTRY alMidiSoundfontSOFT(ALuint id) -{ - alMidiSoundfontvSOFT(1, &id); -} - -AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids) -{ - ALCdevice *device; - ALCcontext *context; - MidiSynth *synth; - ALenum err; - - context = GetContextRef(); - if(!context) return; - - if(count < 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - synth = device->Synth; - - WriteLock(&synth->Lock); - if(synth->State == AL_PLAYING || synth->State == AL_PAUSED) - alSetError(context, AL_INVALID_OPERATION); - else - { - err = V(synth,selectSoundfonts)(context, count, ids); - if(err != AL_NO_ERROR) - alSetError(context, err); - } - WriteUnlock(&synth->Lock); - -done: - ALCcontext_DecRef(context); -} - - -AL_API void AL_APIENTRY alMidiEventSOFT(ALuint64SOFT time, ALenum event, ALsizei channel, ALsizei param1, ALsizei param2) -{ - ALCdevice *device; - ALCcontext *context; - ALenum err; - - context = GetContextRef(); - if(!context) return; - - if(!(event == AL_NOTEOFF_SOFT || event == AL_NOTEON_SOFT || - event == AL_KEYPRESSURE_SOFT || event == AL_CONTROLLERCHANGE_SOFT || - event == AL_PROGRAMCHANGE_SOFT || event == AL_CHANNELPRESSURE_SOFT || - event == AL_PITCHBEND_SOFT)) - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - if(!(channel >= 0 && channel <= 15)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if(!(param1 >= 0 && param1 <= 127)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if(!(param2 >= 0 && param2 <= 127)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - ALCdevice_Lock(device); - err = MidiSynth_insertEvent(device->Synth, time, event|channel, param1, param2); - ALCdevice_Unlock(device); - if(err != AL_NO_ERROR) - alSetError(context, err); - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alMidiSysExSOFT(ALuint64SOFT time, const ALbyte *data, ALsizei size) -{ - ALCdevice *device; - ALCcontext *context; - ALenum err; - - context = GetContextRef(); - if(!context) return; - - if(!data || size < 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - ALCdevice_Lock(device); - err = MidiSynth_insertSysExEvent(device->Synth, time, data, size); - ALCdevice_Unlock(device); - if(err != AL_NO_ERROR) - alSetError(context, err); - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alMidiPlaySOFT(void) -{ - ALCcontext *context; - MidiSynth *synth; - - context = GetContextRef(); - if(!context) return; - - synth = context->Device->Synth; - WriteLock(&synth->Lock); - MidiSynth_setState(synth, AL_PLAYING); - WriteUnlock(&synth->Lock); - - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alMidiPauseSOFT(void) -{ - ALCcontext *context; - MidiSynth *synth; - - context = GetContextRef(); - if(!context) return; - - synth = context->Device->Synth; - WriteLock(&synth->Lock); - MidiSynth_setState(synth, AL_PAUSED); - WriteUnlock(&synth->Lock); - - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alMidiStopSOFT(void) -{ - ALCdevice *device; - ALCcontext *context; - MidiSynth *synth; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - synth = device->Synth; - - WriteLock(&synth->Lock); - MidiSynth_setState(synth, AL_STOPPED); - - ALCdevice_Lock(device); - V0(synth,stop)(); - ALCdevice_Unlock(device); - WriteUnlock(&synth->Lock); - - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alMidiResetSOFT(void) -{ - ALCdevice *device; - ALCcontext *context; - MidiSynth *synth; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - synth = device->Synth; - - WriteLock(&synth->Lock); - MidiSynth_setState(synth, AL_INITIAL); - - ALCdevice_Lock(device); - V0(synth,reset)(); - ALCdevice_Unlock(device); - WriteUnlock(&synth->Lock); - - ALCcontext_DecRef(context); -} - - -AL_API void AL_APIENTRY alMidiGainSOFT(ALfloat value) -{ - ALCdevice *device; - ALCcontext *context; - - context = GetContextRef(); - if(!context) return; - - if(!(value >= 0.0f && isfinite(value))) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - V(device->Synth,setGain)(value); - -done: - ALCcontext_DecRef(context); -} diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/alPreset.c b/love/src/jni/openal-soft-1.17.0/OpenAL32/alPreset.c deleted file mode 100644 index 1934ba05..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/alPreset.c +++ /dev/null @@ -1,339 +0,0 @@ - -#include "config.h" - -#include -#include - -#include "alMain.h" -#include "alMidi.h" -#include "alError.h" -#include "alThunk.h" - -#include "midi/base.h" - - -extern inline struct ALsfpreset *LookupPreset(ALCdevice *device, ALuint id); -extern inline struct ALsfpreset *RemovePreset(ALCdevice *device, ALuint id); - -static void ALsfpreset_Construct(ALsfpreset *self); -static void ALsfpreset_Destruct(ALsfpreset *self); - - -AL_API void AL_APIENTRY alGenPresetsSOFT(ALsizei n, ALuint *ids) -{ - ALCcontext *context; - ALsizei cur = 0; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - for(cur = 0;cur < n;cur++) - { - ALsfpreset *preset = NewPreset(context); - if(!preset) - { - alDeletePresetsSOFT(cur, ids); - break; - } - - ids[cur] = preset->id; - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alDeletePresetsSOFT(ALsizei n, const ALuint *ids) -{ - ALCdevice *device; - ALCcontext *context; - ALsfpreset *preset; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - for(i = 0;i < n;i++) - { - /* Check for valid ID */ - if((preset=LookupPreset(device, ids[i])) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&preset->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - for(i = 0;i < n;i++) - { - if((preset=LookupPreset(device, ids[i])) != NULL) - DeletePreset(device, preset); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALboolean AL_APIENTRY alIsPresetSOFT(ALuint id) -{ - ALCcontext *context; - ALboolean ret; - - context = GetContextRef(); - if(!context) return AL_FALSE; - - ret = LookupPreset(context->Device, id) ? AL_TRUE : AL_FALSE; - - ALCcontext_DecRef(context); - - return ret; -} - -AL_API void AL_APIENTRY alPresetiSOFT(ALuint id, ALenum param, ALint value) -{ - ALCdevice *device; - ALCcontext *context; - ALsfpreset *preset; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if((preset=LookupPreset(device, id)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&preset->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - switch(param) - { - case AL_MIDI_PRESET_SOFT: - if(!(value >= 0 && value <= 127)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - preset->Preset = value; - break; - - case AL_MIDI_BANK_SOFT: - if(!(value >= 0 && value <= 128)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - preset->Bank = value; - break; - - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alPresetivSOFT(ALuint id, ALenum param, const ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - ALsfpreset *preset; - - switch(param) - { - case AL_MIDI_PRESET_SOFT: - case AL_MIDI_BANK_SOFT: - alPresetiSOFT(id, param, values[0]); - return; - } - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if((preset=LookupPreset(device, id)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&preset->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - switch(param) - { - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alGetPresetivSOFT(ALuint id, ALenum param, ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - ALsfpreset *preset; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if((preset=LookupPreset(device, id)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - switch(param) - { - case AL_MIDI_PRESET_SOFT: - values[0] = preset->Preset; - break; - - case AL_MIDI_BANK_SOFT: - values[0] = preset->Bank; - break; - - case AL_FONTSOUNDS_SIZE_SOFT: - values[0] = preset->NumSounds; - break; - - case AL_FONTSOUNDS_SOFT: - for(i = 0;i < preset->NumSounds;i++) - values[i] = preset->Sounds[i]->id; - break; - - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alPresetFontsoundsSOFT(ALuint id, ALsizei count, const ALuint *fsids) -{ - ALCdevice *device; - ALCcontext *context; - ALsfpreset *preset; - ALfontsound **sounds; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(!(preset=LookupPreset(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(count < 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - if(ReadRef(&preset->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - - if(count == 0) - sounds = NULL; - else - { - sounds = calloc(count, sizeof(sounds[0])); - if(!sounds) - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); - - for(i = 0;i < count;i++) - { - if(!(sounds[i]=LookupFontsound(device, fsids[i]))) - { - free(sounds); - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - } - } - } - - for(i = 0;i < count;i++) - IncrementRef(&sounds[i]->ref); - - sounds = ExchangePtr((XchgPtr*)&preset->Sounds, sounds); - count = ExchangeInt(&preset->NumSounds, count); - - for(i = 0;i < count;i++) - DecrementRef(&sounds[i]->ref); - free(sounds); - -done: - ALCcontext_DecRef(context); -} - - -ALsfpreset *NewPreset(ALCcontext *context) -{ - ALCdevice *device = context->Device; - ALsfpreset *preset; - ALenum err; - - preset = calloc(1, sizeof(*preset)); - if(!preset) - SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL); - ALsfpreset_Construct(preset); - - err = NewThunkEntry(&preset->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->PresetMap, preset->id, preset); - if(err != AL_NO_ERROR) - { - ALsfpreset_Destruct(preset); - memset(preset, 0, sizeof(*preset)); - free(preset); - - SET_ERROR_AND_RETURN_VALUE(context, err, NULL); - } - - return preset; -} - -void DeletePreset(ALCdevice *device, ALsfpreset *preset) -{ - RemovePreset(device, preset->id); - - ALsfpreset_Destruct(preset); - memset(preset, 0, sizeof(*preset)); - free(preset); -} - - -static void ALsfpreset_Construct(ALsfpreset *self) -{ - InitRef(&self->ref, 0); - - self->Preset = 0; - self->Bank = 0; - - self->Sounds = NULL; - self->NumSounds = 0; - - self->id = 0; -} - -static void ALsfpreset_Destruct(ALsfpreset *self) -{ - ALsizei i; - - FreeThunkEntry(self->id); - self->id = 0; - - for(i = 0;i < self->NumSounds;i++) - DecrementRef(&self->Sounds[i]->ref); - free(self->Sounds); - self->Sounds = NULL; - self->NumSounds = 0; -} - - -/* ReleaseALPresets - * - * Called to destroy any presets that still exist on the device - */ -void ReleaseALPresets(ALCdevice *device) -{ - ALsizei i; - for(i = 0;i < device->PresetMap.size;i++) - { - ALsfpreset *temp = device->PresetMap.array[i].value; - device->PresetMap.array[i].value = NULL; - - ALsfpreset_Destruct(temp); - - memset(temp, 0, sizeof(*temp)); - free(temp); - } -} diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/alSoundfont.c b/love/src/jni/openal-soft-1.17.0/OpenAL32/alSoundfont.c deleted file mode 100644 index 30c97a3a..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/alSoundfont.c +++ /dev/null @@ -1,454 +0,0 @@ - -#include "config.h" - -#include -#include -#include -#include - -#include "alMain.h" -#include "alMidi.h" -#include "alThunk.h" -#include "alError.h" -#include - -#include "midi/base.h" - - -extern inline struct ALsoundfont *LookupSfont(ALCdevice *device, ALuint id); -extern inline struct ALsoundfont *RemoveSfont(ALCdevice *device, ALuint id); - -static void ALsoundfont_Construct(ALsoundfont *self); -static void ALsoundfont_Destruct(ALsoundfont *self); -void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device); -ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context); -static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr); - - -AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids) -{ - ALCdevice *device; - ALCcontext *context; - ALsizei cur = 0; - ALenum err; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - for(cur = 0;cur < n;cur++) - { - ALsoundfont *sfont = calloc(1, sizeof(ALsoundfont)); - if(!sfont) - { - alDeleteSoundfontsSOFT(cur, ids); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); - } - ALsoundfont_Construct(sfont); - - err = NewThunkEntry(&sfont->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&device->SfontMap, sfont->id, sfont); - if(err != AL_NO_ERROR) - { - ALsoundfont_Destruct(sfont); - memset(sfont, 0, sizeof(ALsoundfont)); - free(sfont); - - alDeleteSoundfontsSOFT(cur, ids); - SET_ERROR_AND_GOTO(context, err, done); - } - - ids[cur] = sfont->id; - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids) -{ - ALCdevice *device; - ALCcontext *context; - ALsoundfont *sfont; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - device = context->Device; - for(i = 0;i < n;i++) - { - /* Check for valid soundfont ID */ - if(ids[i] == 0) - { - if(!(sfont=device->DefaultSfont)) - continue; - } - else if((sfont=LookupSfont(device, ids[i])) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(ReadRef(&sfont->ref) != 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - for(i = 0;i < n;i++) - { - if(ids[i] == 0) - { - MidiSynth *synth = device->Synth; - WriteLock(&synth->Lock); - if(device->DefaultSfont != NULL) - ALsoundfont_deleteSoundfont(device->DefaultSfont, device); - device->DefaultSfont = NULL; - WriteUnlock(&synth->Lock); - continue; - } - else if((sfont=RemoveSfont(device, ids[i])) == NULL) - continue; - - ALsoundfont_Destruct(sfont); - - memset(sfont, 0, sizeof(*sfont)); - free(sfont); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id) -{ - ALCcontext *context; - ALboolean ret; - - context = GetContextRef(); - if(!context) return AL_FALSE; - - ret = ((!id || LookupSfont(context->Device, id)) ? - AL_TRUE : AL_FALSE); - - ALCcontext_DecRef(context); - - return ret; -} - -AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values) -{ - ALCdevice *device; - ALCcontext *context; - ALsoundfont *sfont; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(id == 0) - sfont = ALsoundfont_getDefSoundfont(context); - else if(!(sfont=LookupSfont(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - switch(param) - { - case AL_PRESETS_SIZE_SOFT: - values[0] = sfont->NumPresets; - break; - - case AL_PRESETS_SOFT: - for(i = 0;i < sfont->NumPresets;i++) - values[i] = sfont->Presets[i]->id; - break; - - default: - SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done); - } - -done: - ALCcontext_DecRef(context); -} - -AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids) -{ - ALCdevice *device; - ALCcontext *context; - ALsoundfont *sfont; - ALsfpreset **presets; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(id == 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - if(!(sfont=LookupSfont(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - if(count < 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - WriteLock(&sfont->Lock); - if(ReadRef(&sfont->ref) != 0) - { - WriteUnlock(&sfont->Lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - if(count == 0) - presets = NULL; - else - { - presets = calloc(count, sizeof(presets[0])); - if(!presets) - { - WriteUnlock(&sfont->Lock); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); - } - - for(i = 0;i < count;i++) - { - if(!(presets[i]=LookupPreset(device, pids[i]))) - { - free(presets); - WriteUnlock(&sfont->Lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - } - } - } - - for(i = 0;i < count;i++) - IncrementRef(&presets[i]->ref); - - presets = ExchangePtr((XchgPtr*)&sfont->Presets, presets); - count = ExchangeInt(&sfont->NumPresets, count); - WriteUnlock(&sfont->Lock); - - for(i = 0;i < count;i++) - DecrementRef(&presets[i]->ref); - free(presets); - -done: - ALCcontext_DecRef(context); -} - - -AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_t,ALvoid*), ALvoid *user) -{ - ALCdevice *device; - ALCcontext *context; - ALsoundfont *sfont; - Reader reader; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - if(id == 0) - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - if(!(sfont=LookupSfont(device, id))) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - - WriteLock(&sfont->Lock); - if(ReadRef(&sfont->ref) != 0) - { - WriteUnlock(&sfont->Lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - if(sfont->NumPresets > 0) - { - WriteUnlock(&sfont->Lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - reader.cb = cb; - reader.ptr = user; - reader.error = 0; - loadSf2(&reader, sfont, context); - WriteUnlock(&sfont->Lock); - -done: - ALCcontext_DecRef(context); -} - - -static void ALsoundfont_Construct(ALsoundfont *self) -{ - InitRef(&self->ref, 0); - - self->Presets = NULL; - self->NumPresets = 0; - - RWLockInit(&self->Lock); - - self->id = 0; -} - -static void ALsoundfont_Destruct(ALsoundfont *self) -{ - ALsizei i; - - FreeThunkEntry(self->id); - self->id = 0; - - for(i = 0;i < self->NumPresets;i++) - { - DecrementRef(&self->Presets[i]->ref); - self->Presets[i] = NULL; - } - free(self->Presets); - self->Presets = NULL; - self->NumPresets = 0; -} - -ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context) -{ - ALCdevice *device = context->Device; - al_string fname = AL_STRING_INIT_STATIC(); - const char *namelist; - - if(device->DefaultSfont) - return device->DefaultSfont; - - device->DefaultSfont = calloc(1, sizeof(device->DefaultSfont[0])); - ALsoundfont_Construct(device->DefaultSfont); - - namelist = getenv("ALSOFT_SOUNDFONT"); - if(!namelist || !namelist[0]) - ConfigValueStr("midi", "soundfont", &namelist); - while(namelist && namelist[0]) - { - const char *next, *end; - FILE *f; - - while(*namelist && (isspace(*namelist) || *namelist == ',')) - namelist++; - if(!*namelist) - break; - next = strchr(namelist, ','); - end = next ? next++ : (namelist+strlen(namelist)); - while(--end != namelist && isspace(*end)) { - } - if(end == namelist) - continue; - al_string_append_range(&fname, namelist, end+1); - namelist = next; - - f = OpenDataFile(al_string_get_cstr(fname), "openal/soundfonts"); - if(f == NULL) - ERR("Failed to open %s\n", al_string_get_cstr(fname)); - else - { - Reader reader; - reader.cb = ALsoundfont_read; - reader.ptr = f; - reader.error = 0; - TRACE("Loading %s\n", al_string_get_cstr(fname)); - loadSf2(&reader, device->DefaultSfont, context); - fclose(f); - } - - al_string_clear(&fname); - } - AL_STRING_DEINIT(fname); - - return device->DefaultSfont; -} - -void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device) -{ - ALsfpreset **presets; - ALsizei num_presets; - VECTOR(ALbuffer*) buffers; - ALsizei i; - - VECTOR_INIT(buffers); - presets = ExchangePtr((XchgPtr*)&self->Presets, NULL); - num_presets = ExchangeInt(&self->NumPresets, 0); - - for(i = 0;i < num_presets;i++) - { - ALsfpreset *preset = presets[i]; - ALfontsound **sounds; - ALsizei num_sounds; - ALboolean deleting; - ALsizei j; - - sounds = ExchangePtr((XchgPtr*)&preset->Sounds, NULL); - num_sounds = ExchangeInt(&preset->NumSounds, 0); - - DeletePreset(device, preset); - preset = NULL; - - for(j = 0;j < num_sounds;j++) - DecrementRef(&sounds[j]->ref); - /* Some fontsounds may not be immediately deletable because they're - * linked to another fontsound. When those fontsounds are deleted - * they should become deletable, so use a loop until all fontsounds - * are deleted. */ - do { - deleting = AL_FALSE; - for(j = 0;j < num_sounds;j++) - { - if(sounds[j] && ReadRef(&sounds[j]->ref) == 0) - { - deleting = AL_TRUE; - if(sounds[j]->Buffer) - { - ALbuffer *buffer = sounds[j]->Buffer; - ALbuffer **iter; - -#define MATCH_BUFFER(_i) (buffer == *(_i)) - VECTOR_FIND_IF(iter, ALbuffer*, buffers, MATCH_BUFFER); - if(iter == VECTOR_ITER_END(buffers)) - VECTOR_PUSH_BACK(buffers, buffer); -#undef MATCH_BUFFER - } - DeleteFontsound(device, sounds[j]); - sounds[j] = NULL; - } - } - } while(deleting); - free(sounds); - } - - ALsoundfont_Destruct(self); - free(self); - -#define DELETE_BUFFER(iter) do { \ - assert(ReadRef(&(*(iter))->ref) == 0); \ - DeleteBuffer(device, *(iter)); \ -} while(0) - VECTOR_FOR_EACH(ALbuffer*, buffers, DELETE_BUFFER); - VECTOR_DEINIT(buffers); -#undef DELETE_BUFFER -} - - -static size_t ALsoundfont_read(ALvoid *buf, size_t bytes, ALvoid *ptr) -{ - return fread(buf, 1, bytes, (FILE*)ptr); -} - - -/* ReleaseALSoundfonts - * - * Called to destroy any soundfonts that still exist on the device - */ -void ReleaseALSoundfonts(ALCdevice *device) -{ - ALsizei i; - for(i = 0;i < device->SfontMap.size;i++) - { - ALsoundfont *temp = device->SfontMap.array[i].value; - device->SfontMap.array[i].value = NULL; - - ALsoundfont_Destruct(temp); - - memset(temp, 0, sizeof(*temp)); - free(temp); - } -} diff --git a/love/src/jni/openal-soft-1.17.0/OpenAL32/alSource.c b/love/src/jni/openal-soft-1.17.0/OpenAL32/alSource.c deleted file mode 100644 index 752e2e35..00000000 --- a/love/src/jni/openal-soft-1.17.0/OpenAL32/alSource.c +++ /dev/null @@ -1,2912 +0,0 @@ -/** - * OpenAL cross platform audio library - * Copyright (C) 1999-2007 by authors. - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * Or go to http://www.gnu.org/copyleft/lgpl.html - */ - -#include "config.h" - -#include -#include -#include - -#include "AL/al.h" -#include "AL/alc.h" -#include "alMain.h" -#include "alError.h" -#include "alSource.h" -#include "alBuffer.h" -#include "alThunk.h" -#include "alAuxEffectSlot.h" - -#include "threads.h" - - -enum Resampler DefaultResampler = LinearResampler; -const ALsizei ResamplerPadding[ResamplerMax] = { - 0, /* Point */ - 1, /* Linear */ - 2, /* Cubic */ -}; -const ALsizei ResamplerPrePadding[ResamplerMax] = { - 0, /* Point */ - 0, /* Linear */ - 1, /* Cubic */ -}; - - -extern inline struct ALsource *LookupSource(ALCcontext *context, ALuint id); -extern inline struct ALsource *RemoveSource(ALCcontext *context, ALuint id); - -static ALvoid InitSourceParams(ALsource *Source); -static ALint64 GetSourceOffset(const ALsource *Source); -static ALdouble GetSourceSecOffset(const ALsource *Source); -static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offsets, ALdouble updateLen); -static ALint GetSampleOffset(ALsource *Source); - -typedef enum SrcFloatProp { - sfPitch = AL_PITCH, - sfGain = AL_GAIN, - sfMinGain = AL_MIN_GAIN, - sfMaxGain = AL_MAX_GAIN, - sfMaxDistance = AL_MAX_DISTANCE, - sfRolloffFactor = AL_ROLLOFF_FACTOR, - sfDopplerFactor = AL_DOPPLER_FACTOR, - sfConeOuterGain = AL_CONE_OUTER_GAIN, - sfSecOffset = AL_SEC_OFFSET, - sfSampleOffset = AL_SAMPLE_OFFSET, - sfByteOffset = AL_BYTE_OFFSET, - sfConeInnerAngle = AL_CONE_INNER_ANGLE, - sfConeOuterAngle = AL_CONE_OUTER_ANGLE, - sfRefDistance = AL_REFERENCE_DISTANCE, - - sfPosition = AL_POSITION, - sfVelocity = AL_VELOCITY, - sfDirection = AL_DIRECTION, - - sfSourceRelative = AL_SOURCE_RELATIVE, - sfLooping = AL_LOOPING, - sfBuffer = AL_BUFFER, - sfSourceState = AL_SOURCE_STATE, - sfBuffersQueued = AL_BUFFERS_QUEUED, - sfBuffersProcessed = AL_BUFFERS_PROCESSED, - sfSourceType = AL_SOURCE_TYPE, - - /* ALC_EXT_EFX */ - sfConeOuterGainHF = AL_CONE_OUTER_GAINHF, - sfAirAbsorptionFactor = AL_AIR_ABSORPTION_FACTOR, - sfRoomRolloffFactor = AL_ROOM_ROLLOFF_FACTOR, - sfDirectFilterGainHFAuto = AL_DIRECT_FILTER_GAINHF_AUTO, - sfAuxSendFilterGainAuto = AL_AUXILIARY_SEND_FILTER_GAIN_AUTO, - sfAuxSendFilterGainHFAuto = AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO, - - /* AL_SOFT_direct_channels */ - sfDirectChannelsSOFT = AL_DIRECT_CHANNELS_SOFT, - - /* AL_EXT_source_distance_model */ - sfDistanceModel = AL_DISTANCE_MODEL, - - sfSecLength = AL_SEC_LENGTH_SOFT, - - /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */ - sfSampleRWOffsetsSOFT = AL_SAMPLE_RW_OFFSETS_SOFT, - sfByteRWOffsetsSOFT = AL_BYTE_RW_OFFSETS_SOFT, - - /* AL_SOFT_source_latency */ - sfSecOffsetLatencySOFT = AL_SEC_OFFSET_LATENCY_SOFT, -} SrcFloatProp; - -typedef enum SrcIntProp { - siMaxDistance = AL_MAX_DISTANCE, - siRolloffFactor = AL_ROLLOFF_FACTOR, - siRefDistance = AL_REFERENCE_DISTANCE, - siSourceRelative = AL_SOURCE_RELATIVE, - siConeInnerAngle = AL_CONE_INNER_ANGLE, - siConeOuterAngle = AL_CONE_OUTER_ANGLE, - siLooping = AL_LOOPING, - siBuffer = AL_BUFFER, - siSourceState = AL_SOURCE_STATE, - siBuffersQueued = AL_BUFFERS_QUEUED, - siBuffersProcessed = AL_BUFFERS_PROCESSED, - siSourceType = AL_SOURCE_TYPE, - siSecOffset = AL_SEC_OFFSET, - siSampleOffset = AL_SAMPLE_OFFSET, - siByteOffset = AL_BYTE_OFFSET, - siDopplerFactor = AL_DOPPLER_FACTOR, - siPosition = AL_POSITION, - siVelocity = AL_VELOCITY, - siDirection = AL_DIRECTION, - - /* ALC_EXT_EFX */ - siDirectFilterGainHFAuto = AL_DIRECT_FILTER_GAINHF_AUTO, - siAuxSendFilterGainAutio = AL_AUXILIARY_SEND_FILTER_GAIN_AUTO, - siAuxSendFilterGainHFAuto = AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO, - siDirectFilter = AL_DIRECT_FILTER, - siAuxSendFilter = AL_AUXILIARY_SEND_FILTER, - - /* AL_SOFT_direct_channels */ - siDirectChannelsSOFT = AL_DIRECT_CHANNELS_SOFT, - - /* AL_EXT_source_distance_model */ - siDistanceModel = AL_DISTANCE_MODEL, - - siByteLength = AL_BYTE_LENGTH_SOFT, - siSampleLength = AL_SAMPLE_LENGTH_SOFT, - - /* AL_SOFT_buffer_sub_data / AL_SOFT_buffer_samples */ - siSampleRWOffsetsSOFT = AL_SAMPLE_RW_OFFSETS_SOFT, - siByteRWOffsetsSOFT = AL_BYTE_RW_OFFSETS_SOFT, - - /* AL_SOFT_source_latency */ - siSampleOffsetLatencySOFT = AL_SAMPLE_OFFSET_LATENCY_SOFT, -} SrcIntProp; - -static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values); -static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values); -static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values); - -static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values); -static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values); -static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values); - -static ALint FloatValsByProp(ALenum prop) -{ - if(prop != (ALenum)((SrcFloatProp)prop)) - return 0; - switch((SrcFloatProp)prop) - { - case sfPitch: - case sfGain: - case sfMinGain: - case sfMaxGain: - case sfMaxDistance: - case sfRolloffFactor: - case sfDopplerFactor: - case sfConeOuterGain: - case sfSecOffset: - case sfSampleOffset: - case sfByteOffset: - case sfConeInnerAngle: - case sfConeOuterAngle: - case sfRefDistance: - case sfConeOuterGainHF: - case sfAirAbsorptionFactor: - case sfRoomRolloffFactor: - case sfDirectFilterGainHFAuto: - case sfAuxSendFilterGainAuto: - case sfAuxSendFilterGainHFAuto: - case sfDirectChannelsSOFT: - case sfDistanceModel: - case sfSourceRelative: - case sfLooping: - case sfBuffer: - case sfSourceState: - case sfBuffersQueued: - case sfBuffersProcessed: - case sfSourceType: - case sfSecLength: - return 1; - - case sfSampleRWOffsetsSOFT: - case sfByteRWOffsetsSOFT: - return 2; - - case sfPosition: - case sfVelocity: - case sfDirection: - return 3; - - case sfSecOffsetLatencySOFT: - break; /* Double only */ - } - return 0; -} -static ALint DoubleValsByProp(ALenum prop) -{ - if(prop != (ALenum)((SrcFloatProp)prop)) - return 0; - switch((SrcFloatProp)prop) - { - case sfPitch: - case sfGain: - case sfMinGain: - case sfMaxGain: - case sfMaxDistance: - case sfRolloffFactor: - case sfDopplerFactor: - case sfConeOuterGain: - case sfSecOffset: - case sfSampleOffset: - case sfByteOffset: - case sfConeInnerAngle: - case sfConeOuterAngle: - case sfRefDistance: - case sfConeOuterGainHF: - case sfAirAbsorptionFactor: - case sfRoomRolloffFactor: - case sfDirectFilterGainHFAuto: - case sfAuxSendFilterGainAuto: - case sfAuxSendFilterGainHFAuto: - case sfDirectChannelsSOFT: - case sfDistanceModel: - case sfSourceRelative: - case sfLooping: - case sfBuffer: - case sfSourceState: - case sfBuffersQueued: - case sfBuffersProcessed: - case sfSourceType: - case sfSecLength: - return 1; - - case sfSampleRWOffsetsSOFT: - case sfByteRWOffsetsSOFT: - case sfSecOffsetLatencySOFT: - return 2; - - case sfPosition: - case sfVelocity: - case sfDirection: - return 3; - } - return 0; -} - -static ALint IntValsByProp(ALenum prop) -{ - if(prop != (ALenum)((SrcIntProp)prop)) - return 0; - switch((SrcIntProp)prop) - { - case siMaxDistance: - case siRolloffFactor: - case siRefDistance: - case siSourceRelative: - case siConeInnerAngle: - case siConeOuterAngle: - case siLooping: - case siBuffer: - case siSourceState: - case siBuffersQueued: - case siBuffersProcessed: - case siSourceType: - case siSecOffset: - case siSampleOffset: - case siByteOffset: - case siDopplerFactor: - case siDirectFilterGainHFAuto: - case siAuxSendFilterGainAutio: - case siAuxSendFilterGainHFAuto: - case siDirectFilter: - case siDirectChannelsSOFT: - case siDistanceModel: - case siByteLength: - case siSampleLength: - return 1; - - case siSampleRWOffsetsSOFT: - case siByteRWOffsetsSOFT: - return 2; - - case siPosition: - case siVelocity: - case siDirection: - case siAuxSendFilter: - return 3; - - case siSampleOffsetLatencySOFT: - break; /* i64 only */ - } - return 0; -} -static ALint Int64ValsByProp(ALenum prop) -{ - if(prop != (ALenum)((SrcIntProp)prop)) - return 0; - switch((SrcIntProp)prop) - { - case siMaxDistance: - case siRolloffFactor: - case siRefDistance: - case siSourceRelative: - case siConeInnerAngle: - case siConeOuterAngle: - case siLooping: - case siBuffer: - case siSourceState: - case siBuffersQueued: - case siBuffersProcessed: - case siSourceType: - case siSecOffset: - case siSampleOffset: - case siByteOffset: - case siDopplerFactor: - case siDirectFilterGainHFAuto: - case siAuxSendFilterGainAutio: - case siAuxSendFilterGainHFAuto: - case siDirectFilter: - case siDirectChannelsSOFT: - case siDistanceModel: - case siByteLength: - case siSampleLength: - return 1; - - case siSampleRWOffsetsSOFT: - case siByteRWOffsetsSOFT: - case siSampleOffsetLatencySOFT: - return 2; - - case siPosition: - case siVelocity: - case siDirection: - case siAuxSendFilter: - return 3; - } - return 0; -} - - -#define CHECKVAL(x) do { \ - if(!(x)) \ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); \ -} while(0) - -static ALboolean SetSourcefv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, const ALfloat *values) -{ - ALint ival; - - switch(prop) - { - case AL_PITCH: - CHECKVAL(*values >= 0.0f); - - Source->Pitch = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_CONE_INNER_ANGLE: - CHECKVAL(*values >= 0.0f && *values <= 360.0f); - - Source->InnerAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_CONE_OUTER_ANGLE: - CHECKVAL(*values >= 0.0f && *values <= 360.0f); - - Source->OuterAngle = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_GAIN: - CHECKVAL(*values >= 0.0f); - - Source->Gain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_MAX_DISTANCE: - CHECKVAL(*values >= 0.0f); - - Source->MaxDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_ROLLOFF_FACTOR: - CHECKVAL(*values >= 0.0f); - - Source->RollOffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_REFERENCE_DISTANCE: - CHECKVAL(*values >= 0.0f); - - Source->RefDistance = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_MIN_GAIN: - CHECKVAL(*values >= 0.0f && *values <= 1.0f); - - Source->MinGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_MAX_GAIN: - CHECKVAL(*values >= 0.0f && *values <= 1.0f); - - Source->MaxGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_CONE_OUTER_GAIN: - CHECKVAL(*values >= 0.0f && *values <= 1.0f); - - Source->OuterGain = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_CONE_OUTER_GAINHF: - CHECKVAL(*values >= 0.0f && *values <= 1.0f); - - Source->OuterGainHF = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_AIR_ABSORPTION_FACTOR: - CHECKVAL(*values >= 0.0f && *values <= 10.0f); - - Source->AirAbsorptionFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_ROOM_ROLLOFF_FACTOR: - CHECKVAL(*values >= 0.0f && *values <= 10.0f); - - Source->RoomRolloffFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_DOPPLER_FACTOR: - CHECKVAL(*values >= 0.0f && *values <= 1.0f); - - Source->DopplerFactor = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - CHECKVAL(*values >= 0.0f); - - LockContext(Context); - Source->OffsetType = prop; - Source->Offset = *values; - - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) - { - if(ApplyOffset(Source) == AL_FALSE) - { - UnlockContext(Context); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); - } - } - UnlockContext(Context); - return AL_TRUE; - - - case sfSecLength: - case AL_SEC_OFFSET_LATENCY_SOFT: - /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - - - case AL_POSITION: - CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - - LockContext(Context); - Source->Position[0] = values[0]; - Source->Position[1] = values[1]; - Source->Position[2] = values[2]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_VELOCITY: - CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - - LockContext(Context); - Source->Velocity[0] = values[0]; - Source->Velocity[1] = values[1]; - Source->Velocity[2] = values[2]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_DIRECTION: - CHECKVAL(isfinite(values[0]) && isfinite(values[1]) && isfinite(values[2])); - - LockContext(Context); - Source->Orientation[0] = values[0]; - Source->Orientation[1] = values[1]; - Source->Orientation[2] = values[2]; - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - - case sfSampleRWOffsetsSOFT: - case sfByteRWOffsetsSOFT: - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - - - case sfSourceRelative: - case sfLooping: - case sfSourceState: - case sfSourceType: - case sfDistanceModel: - case sfDirectFilterGainHFAuto: - case sfAuxSendFilterGainAuto: - case sfAuxSendFilterGainHFAuto: - case sfDirectChannelsSOFT: - ival = (ALint)values[0]; - return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); - - case sfBuffer: - case sfBuffersQueued: - case sfBuffersProcessed: - ival = (ALint)((ALuint)values[0]); - return SetSourceiv(Source, Context, (SrcIntProp)prop, &ival); - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - -static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint *values) -{ - ALCdevice *device = Context->Device; - ALbuffer *buffer = NULL; - ALfilter *filter = NULL; - ALeffectslot *slot = NULL; - ALbufferlistitem *oldlist; - ALbufferlistitem *newlist; - ALfloat fvals[3]; - - switch(prop) - { - case AL_SOURCE_RELATIVE: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->HeadRelative = (ALboolean)*values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_LOOPING: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->Looping = (ALboolean)*values; - return AL_TRUE; - - case AL_BUFFER: - CHECKVAL(*values == 0 || (buffer=LookupBuffer(device, *values)) != NULL); - - WriteLock(&Source->queue_lock); - if(!(Source->state == AL_STOPPED || Source->state == AL_INITIAL)) - { - WriteUnlock(&Source->queue_lock); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - } - - if(buffer != NULL) - { - /* Add the selected buffer to a one-item queue */ - newlist = malloc(sizeof(ALbufferlistitem)); - newlist->buffer = buffer; - newlist->next = NULL; - newlist->prev = NULL; - IncrementRef(&buffer->ref); - - /* Source is now Static */ - Source->SourceType = AL_STATIC; - - ReadLock(&buffer->lock); - Source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - Source->SampleSize = BytesFromFmt(buffer->FmtType); - ReadUnlock(&buffer->lock); - } - else - { - /* Source is now Undetermined */ - Source->SourceType = AL_UNDETERMINED; - newlist = NULL; - } - oldlist = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, newlist); - ATOMIC_STORE(&Source->current_buffer, newlist); - WriteUnlock(&Source->queue_lock); - - /* Delete all elements in the previous queue */ - while(oldlist != NULL) - { - ALbufferlistitem *temp = oldlist; - oldlist = temp->next; - - if(temp->buffer) - DecrementRef(&temp->buffer->ref); - free(temp); - } - return AL_TRUE; - - case siSourceState: - case siSourceType: - case siBuffersQueued: - case siBuffersProcessed: - /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - CHECKVAL(*values >= 0); - - LockContext(Context); - Source->OffsetType = prop; - Source->Offset = *values; - - if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) && - !Context->DeferUpdates) - { - if(ApplyOffset(Source) == AL_FALSE) - { - UnlockContext(Context); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); - } - } - UnlockContext(Context); - return AL_TRUE; - - - case siByteLength: - case siSampleLength: - case siSampleRWOffsetsSOFT: - case siByteRWOffsetsSOFT: - /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - - - case AL_DIRECT_FILTER: - CHECKVAL(*values == 0 || (filter=LookupFilter(device, *values)) != NULL); - - LockContext(Context); - if(!filter) - { - Source->Direct.Gain = 1.0f; - Source->Direct.GainHF = 1.0f; - Source->Direct.HFReference = LOWPASSFREQREF; - Source->Direct.GainLF = 1.0f; - Source->Direct.LFReference = HIGHPASSFREQREF; - } - else - { - Source->Direct.Gain = filter->Gain; - Source->Direct.GainHF = filter->GainHF; - Source->Direct.HFReference = filter->HFReference; - Source->Direct.GainLF = filter->GainLF; - Source->Direct.LFReference = filter->LFReference; - } - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_DIRECT_FILTER_GAINHF_AUTO: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->DryGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->WetGainAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->WetGainHFAuto = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_DIRECT_CHANNELS_SOFT: - CHECKVAL(*values == AL_FALSE || *values == AL_TRUE); - - Source->DirectChannels = *values; - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - case AL_DISTANCE_MODEL: - CHECKVAL(*values == AL_NONE || - *values == AL_INVERSE_DISTANCE || - *values == AL_INVERSE_DISTANCE_CLAMPED || - *values == AL_LINEAR_DISTANCE || - *values == AL_LINEAR_DISTANCE_CLAMPED || - *values == AL_EXPONENT_DISTANCE || - *values == AL_EXPONENT_DISTANCE_CLAMPED); - - Source->DistanceModel = *values; - if(Context->SourceDistanceModel) - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - - case AL_AUXILIARY_SEND_FILTER: - LockContext(Context); - if(!((ALuint)values[1] < device->NumAuxSends && - (values[0] == 0 || (slot=LookupEffectSlot(Context, values[0])) != NULL) && - (values[2] == 0 || (filter=LookupFilter(device, values[2])) != NULL))) - { - UnlockContext(Context); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_VALUE, AL_FALSE); - } - - /* Add refcount on the new slot, and release the previous slot */ - if(slot) IncrementRef(&slot->ref); - slot = ExchangePtr((XchgPtr*)&Source->Send[values[1]].Slot, slot); - if(slot) DecrementRef(&slot->ref); - - if(!filter) - { - /* Disable filter */ - Source->Send[values[1]].Gain = 1.0f; - Source->Send[values[1]].GainHF = 1.0f; - Source->Send[values[1]].HFReference = LOWPASSFREQREF; - Source->Send[values[1]].GainLF = 1.0f; - Source->Send[values[1]].LFReference = HIGHPASSFREQREF; - } - else - { - Source->Send[values[1]].Gain = filter->Gain; - Source->Send[values[1]].GainHF = filter->GainHF; - Source->Send[values[1]].HFReference = filter->HFReference; - Source->Send[values[1]].GainLF = filter->GainLF; - Source->Send[values[1]].LFReference = filter->LFReference; - } - UnlockContext(Context); - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - return AL_TRUE; - - - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_REFERENCE_DISTANCE: - case siDopplerFactor: - fvals[0] = (ALfloat)*values; - return SetSourcefv(Source, Context, (int)prop, fvals); - - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - fvals[0] = (ALfloat)values[0]; - fvals[1] = (ALfloat)values[1]; - fvals[2] = (ALfloat)values[2]; - return SetSourcefv(Source, Context, (int)prop, fvals); - - case siSampleOffsetLatencySOFT: - /* i64 only */ - break; - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - -static ALboolean SetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, const ALint64SOFT *values) -{ - ALfloat fvals[3]; - ALint ivals[3]; - - switch(prop) - { - case siSampleRWOffsetsSOFT: - case siByteRWOffsetsSOFT: - case siSampleOffsetLatencySOFT: - /* Query only */ - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_OPERATION, AL_FALSE); - - - /* 1x int */ - case AL_SOURCE_RELATIVE: - case AL_LOOPING: - case AL_SOURCE_STATE: - case AL_BYTE_OFFSET: - case AL_SAMPLE_OFFSET: - case siByteLength: - case siSampleLength: - case siSourceType: - case siBuffersQueued: - case siBuffersProcessed: - case AL_DIRECT_FILTER_GAINHF_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - case AL_DIRECT_CHANNELS_SOFT: - case AL_DISTANCE_MODEL: - CHECKVAL(*values <= INT_MAX && *values >= INT_MIN); - - ivals[0] = (ALint)*values; - return SetSourceiv(Source, Context, (int)prop, ivals); - - /* 1x uint */ - case AL_BUFFER: - case AL_DIRECT_FILTER: - CHECKVAL(*values <= UINT_MAX && *values >= 0); - - ivals[0] = (ALuint)*values; - return SetSourceiv(Source, Context, (int)prop, ivals); - - /* 3x uint */ - case AL_AUXILIARY_SEND_FILTER: - CHECKVAL(values[0] <= UINT_MAX && values[0] >= 0 && - values[1] <= UINT_MAX && values[1] >= 0 && - values[2] <= UINT_MAX && values[2] >= 0); - - ivals[0] = (ALuint)values[0]; - ivals[1] = (ALuint)values[1]; - ivals[2] = (ALuint)values[2]; - return SetSourceiv(Source, Context, (int)prop, ivals); - - /* 1x float */ - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_REFERENCE_DISTANCE: - case AL_SEC_OFFSET: - case siDopplerFactor: - fvals[0] = (ALfloat)*values; - return SetSourcefv(Source, Context, (int)prop, fvals); - - /* 3x float */ - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - fvals[0] = (ALfloat)values[0]; - fvals[1] = (ALfloat)values[1]; - fvals[2] = (ALfloat)values[2]; - return SetSourcefv(Source, Context, (int)prop, fvals); - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - -#undef CHECKVAL - - -static ALboolean GetSourcedv(ALsource *Source, ALCcontext *Context, SrcFloatProp prop, ALdouble *values) -{ - ALbufferlistitem *BufferList; - ALdouble offsets[2]; - ALdouble updateLen; - ALint ivals[3]; - ALboolean err; - - switch(prop) - { - case AL_GAIN: - *values = Source->Gain; - return AL_TRUE; - - case AL_PITCH: - *values = Source->Pitch; - return AL_TRUE; - - case AL_MAX_DISTANCE: - *values = Source->MaxDistance; - return AL_TRUE; - - case AL_ROLLOFF_FACTOR: - *values = Source->RollOffFactor; - return AL_TRUE; - - case AL_REFERENCE_DISTANCE: - *values = Source->RefDistance; - return AL_TRUE; - - case AL_CONE_INNER_ANGLE: - *values = Source->InnerAngle; - return AL_TRUE; - - case AL_CONE_OUTER_ANGLE: - *values = Source->OuterAngle; - return AL_TRUE; - - case AL_MIN_GAIN: - *values = Source->MinGain; - return AL_TRUE; - - case AL_MAX_GAIN: - *values = Source->MaxGain; - return AL_TRUE; - - case AL_CONE_OUTER_GAIN: - *values = Source->OuterGain; - return AL_TRUE; - - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - LockContext(Context); - ReadLock(&Source->queue_lock); - GetSourceOffsets(Source, prop, offsets, 0.0); - ReadUnlock(&Source->queue_lock); - UnlockContext(Context); - *values = offsets[0]; - return AL_TRUE; - - case AL_CONE_OUTER_GAINHF: - *values = Source->OuterGainHF; - return AL_TRUE; - - case AL_AIR_ABSORPTION_FACTOR: - *values = Source->AirAbsorptionFactor; - return AL_TRUE; - - case AL_ROOM_ROLLOFF_FACTOR: - *values = Source->RoomRolloffFactor; - return AL_TRUE; - - case AL_DOPPLER_FACTOR: - *values = Source->DopplerFactor; - return AL_TRUE; - - case sfSecLength: - ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) - *values = 0; - else - { - ALint length = 0; - ALsizei freq = 1; - do { - ALbuffer *buffer = BufferList->buffer; - if(buffer && buffer->SampleLen > 0) - { - freq = buffer->Frequency; - length += buffer->SampleLen; - } - } while((BufferList=BufferList->next) != NULL); - *values = (ALdouble)length / (ALdouble)freq; - } - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case AL_SAMPLE_RW_OFFSETS_SOFT: - case AL_BYTE_RW_OFFSETS_SOFT: - LockContext(Context); - ReadLock(&Source->queue_lock); - updateLen = (ALdouble)Context->Device->UpdateSize / - Context->Device->Frequency; - GetSourceOffsets(Source, prop, values, updateLen); - ReadUnlock(&Source->queue_lock); - UnlockContext(Context); - return AL_TRUE; - - case AL_SEC_OFFSET_LATENCY_SOFT: - LockContext(Context); - ReadLock(&Source->queue_lock); - values[0] = GetSourceSecOffset(Source); - ReadUnlock(&Source->queue_lock); - values[1] = (ALdouble)ALCdevice_GetLatency(Context->Device) / - 1000000000.0; - UnlockContext(Context); - return AL_TRUE; - - case AL_POSITION: - LockContext(Context); - values[0] = Source->Position[0]; - values[1] = Source->Position[1]; - values[2] = Source->Position[2]; - UnlockContext(Context); - return AL_TRUE; - - case AL_VELOCITY: - LockContext(Context); - values[0] = Source->Velocity[0]; - values[1] = Source->Velocity[1]; - values[2] = Source->Velocity[2]; - UnlockContext(Context); - return AL_TRUE; - - case AL_DIRECTION: - LockContext(Context); - values[0] = Source->Orientation[0]; - values[1] = Source->Orientation[1]; - values[2] = Source->Orientation[2]; - UnlockContext(Context); - return AL_TRUE; - - case AL_SOURCE_RELATIVE: - case AL_LOOPING: - case AL_BUFFER: - case AL_SOURCE_STATE: - case AL_BUFFERS_QUEUED: - case AL_BUFFERS_PROCESSED: - case AL_SOURCE_TYPE: - case AL_DIRECT_FILTER_GAINHF_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - case AL_DIRECT_CHANNELS_SOFT: - case AL_DISTANCE_MODEL: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) - *values = (ALdouble)ivals[0]; - return err; - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - -static ALboolean GetSourceiv(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint *values) -{ - ALbufferlistitem *BufferList; - ALdouble dvals[3]; - ALboolean err; - - switch(prop) - { - case AL_SOURCE_RELATIVE: - *values = Source->HeadRelative; - return AL_TRUE; - - case AL_LOOPING: - *values = Source->Looping; - return AL_TRUE; - - case AL_BUFFER: - ReadLock(&Source->queue_lock); - BufferList = (Source->SourceType == AL_STATIC) ? ATOMIC_LOAD(&Source->queue) : - ATOMIC_LOAD(&Source->current_buffer); - *values = (BufferList && BufferList->buffer) ? BufferList->buffer->id : 0; - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case AL_SOURCE_STATE: - *values = Source->state; - return AL_TRUE; - - case siByteLength: - ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) - *values = 0; - else - { - ALint length = 0; - do { - ALbuffer *buffer = BufferList->buffer; - if(buffer && buffer->SampleLen > 0) - { - ALuint byte_align, sample_align; - if(buffer->OriginalType == UserFmtIMA4) - { - ALsizei align = (buffer->OriginalAlign-1)/2 + 4; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; - } - else if(buffer->OriginalType == UserFmtMSADPCM) - { - ALsizei align = (buffer->OriginalAlign-2)/2 + 7; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; - } - else - { - ALsizei align = buffer->OriginalAlign; - byte_align = align * ChannelsFromFmt(buffer->FmtChannels); - sample_align = buffer->OriginalAlign; - } - - length += buffer->SampleLen / sample_align * byte_align; - } - } while((BufferList=BufferList->next) != NULL); - *values = length; - } - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case siSampleLength: - ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) - *values = 0; - else - { - ALint length = 0; - do { - ALbuffer *buffer = BufferList->buffer; - if(buffer) length += buffer->SampleLen; - } while((BufferList=BufferList->next) != NULL); - *values = length; - } - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case AL_BUFFERS_QUEUED: - ReadLock(&Source->queue_lock); - if(!(BufferList=ATOMIC_LOAD(&Source->queue))) - *values = 0; - else - { - ALsizei count = 0; - do { - ++count; - } while((BufferList=BufferList->next) != NULL); - *values = count; - } - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case AL_BUFFERS_PROCESSED: - ReadLock(&Source->queue_lock); - if(Source->Looping || Source->SourceType != AL_STREAMING) - { - /* Buffers on a looping source are in a perpetual state of - * PENDING, so don't report any as PROCESSED */ - *values = 0; - } - else - { - const ALbufferlistitem *BufferList = ATOMIC_LOAD(&Source->queue); - const ALbufferlistitem *Current = ATOMIC_LOAD(&Source->current_buffer); - ALsizei played = 0; - while(BufferList && BufferList != Current) - { - played++; - BufferList = BufferList->next; - } - *values = played; - } - ReadUnlock(&Source->queue_lock); - return AL_TRUE; - - case AL_SOURCE_TYPE: - *values = Source->SourceType; - return AL_TRUE; - - case AL_DIRECT_FILTER_GAINHF_AUTO: - *values = Source->DryGainHFAuto; - return AL_TRUE; - - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - *values = Source->WetGainAuto; - return AL_TRUE; - - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - *values = Source->WetGainHFAuto; - return AL_TRUE; - - case AL_DIRECT_CHANNELS_SOFT: - *values = Source->DirectChannels; - return AL_TRUE; - - case AL_DISTANCE_MODEL: - *values = Source->DistanceModel; - return AL_TRUE; - - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_REFERENCE_DISTANCE: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - case AL_DOPPLER_FACTOR: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - *values = (ALint)dvals[0]; - return err; - - case AL_SAMPLE_RW_OFFSETS_SOFT: - case AL_BYTE_RW_OFFSETS_SOFT: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - { - values[0] = (ALint)dvals[0]; - values[1] = (ALint)dvals[1]; - } - return err; - - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - { - values[0] = (ALint)dvals[0]; - values[1] = (ALint)dvals[1]; - values[2] = (ALint)dvals[2]; - } - return err; - - case siSampleOffsetLatencySOFT: - /* i64 only */ - break; - - case siDirectFilter: - case siAuxSendFilter: - /* ??? */ - break; - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - -static ALboolean GetSourcei64v(ALsource *Source, ALCcontext *Context, SrcIntProp prop, ALint64 *values) -{ - ALdouble dvals[3]; - ALint ivals[3]; - ALboolean err; - - switch(prop) - { - case AL_SAMPLE_OFFSET_LATENCY_SOFT: - LockContext(Context); - ReadLock(&Source->queue_lock); - values[0] = GetSourceOffset(Source); - ReadUnlock(&Source->queue_lock); - values[1] = ALCdevice_GetLatency(Context->Device); - UnlockContext(Context); - return AL_TRUE; - - case AL_MAX_DISTANCE: - case AL_ROLLOFF_FACTOR: - case AL_REFERENCE_DISTANCE: - case AL_CONE_INNER_ANGLE: - case AL_CONE_OUTER_ANGLE: - case AL_SEC_OFFSET: - case AL_SAMPLE_OFFSET: - case AL_BYTE_OFFSET: - case AL_DOPPLER_FACTOR: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - *values = (ALint64)dvals[0]; - return err; - - case AL_SAMPLE_RW_OFFSETS_SOFT: - case AL_BYTE_RW_OFFSETS_SOFT: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - { - values[0] = (ALint64)dvals[0]; - values[1] = (ALint64)dvals[1]; - } - return err; - - case AL_POSITION: - case AL_VELOCITY: - case AL_DIRECTION: - if((err=GetSourcedv(Source, Context, (int)prop, dvals)) != AL_FALSE) - { - values[0] = (ALint64)dvals[0]; - values[1] = (ALint64)dvals[1]; - values[2] = (ALint64)dvals[2]; - } - return err; - - case AL_SOURCE_RELATIVE: - case AL_LOOPING: - case AL_SOURCE_STATE: - case AL_BUFFERS_QUEUED: - case AL_BUFFERS_PROCESSED: - case siByteLength: - case siSampleLength: - case AL_SOURCE_TYPE: - case AL_DIRECT_FILTER_GAINHF_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAIN_AUTO: - case AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO: - case AL_DIRECT_CHANNELS_SOFT: - case AL_DISTANCE_MODEL: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) - *values = ivals[0]; - return err; - - case siBuffer: - case siDirectFilter: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) - *values = (ALuint)ivals[0]; - return err; - - case siAuxSendFilter: - if((err=GetSourceiv(Source, Context, (int)prop, ivals)) != AL_FALSE) - { - values[0] = (ALuint)ivals[0]; - values[1] = (ALuint)ivals[1]; - values[2] = (ALuint)ivals[2]; - } - return err; - } - - ERR("Unexpected property: 0x%04x\n", prop); - SET_ERROR_AND_RETURN_VALUE(Context, AL_INVALID_ENUM, AL_FALSE); -} - - -AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) -{ - ALCcontext *context; - ALsizei cur = 0; - ALenum err; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(cur = 0;cur < n;cur++) - { - ALsource *source = al_calloc(16, sizeof(ALsource)); - if(!source) - { - alDeleteSources(cur, sources); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); - } - InitSourceParams(source); - - err = NewThunkEntry(&source->id); - if(err == AL_NO_ERROR) - err = InsertUIntMapEntry(&context->SourceMap, source->id, source); - if(err != AL_NO_ERROR) - { - FreeThunkEntry(source->id); - memset(source, 0, sizeof(ALsource)); - al_free(source); - - alDeleteSources(cur, sources); - SET_ERROR_AND_GOTO(context, err, done); - } - - sources[cur] = source->id; - } - -done: - ALCcontext_DecRef(context); -} - - -AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) -{ - ALCcontext *context; - ALbufferlistitem *BufferList; - ALsource *Source; - ALsizei i, j; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - /* Check that all Sources are valid */ - for(i = 0;i < n;i++) - { - if(LookupSource(context, sources[i]) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - } - for(i = 0;i < n;i++) - { - ALactivesource **srclist, **srclistend; - - if((Source=RemoveSource(context, sources[i])) == NULL) - continue; - FreeThunkEntry(Source->id); - - LockContext(context); - srclist = context->ActiveSources; - srclistend = srclist + context->ActiveSourceCount; - while(srclist != srclistend) - { - if((*srclist)->Source == Source) - { - ALactivesource *temp = *(--srclistend); - *srclistend = *srclist; - *srclist = temp; - --(context->ActiveSourceCount); - break; - } - srclist++; - } - UnlockContext(context); - - BufferList = ATOMIC_EXCHANGE(ALbufferlistitem*, &Source->queue, NULL); - while(BufferList != NULL) - { - ALbufferlistitem *next = BufferList->next; - if(BufferList->buffer != NULL) - DecrementRef(&BufferList->buffer->ref); - free(BufferList); - BufferList = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(Source->Send[j].Slot) - DecrementRef(&Source->Send[j].Slot->ref); - Source->Send[j].Slot = NULL; - } - - memset(Source, 0, sizeof(*Source)); - al_free(Source); - } - -done: - ALCcontext_DecRef(context); -} - - -AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) -{ - ALCcontext *context; - ALboolean ret; - - context = GetContextRef(); - if(!context) return AL_FALSE; - - ret = (LookupSource(context, source) ? AL_TRUE : AL_FALSE); - - ALCcontext_DecRef(context); - - return ret; -} - - -AL_API ALvoid AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(FloatValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourcefv(Source, Context, param, &value); - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(FloatValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALfloat fvals[3] = { value1, value2, value3 }; - SetSourcefv(Source, Context, param, fvals); - } - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(FloatValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourcefv(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(DoubleValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALfloat fval = (ALfloat)value; - SetSourcefv(Source, Context, param, &fval); - } - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(DoubleValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALfloat fvals[3] = { (ALfloat)value1, (ALfloat)value2, (ALfloat)value3 }; - SetSourcefv(Source, Context, param, fvals); - } - - ALCcontext_DecRef(Context); -} - -AL_API ALvoid AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values) -{ - ALCcontext *Context; - ALsource *Source; - ALint count; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!((count=DoubleValsByProp(param)) > 0 && count <= 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALfloat fvals[3]; - ALint i; - - for(i = 0;i < count;i++) - fvals[i] = (ALfloat)values[i]; - SetSourcefv(Source, Context, param, fvals); - } - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(IntValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourceiv(Source, Context, param, &value); - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(IntValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALint ivals[3] = { value1, value2, value3 }; - SetSourceiv(Source, Context, param, ivals); - } - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(IntValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourceiv(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(Int64ValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourcei64v(Source, Context, param, &value); - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(Int64ValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALint64SOFT i64vals[3] = { value1, value2, value3 }; - SetSourcei64v(Source, Context, param, i64vals); - } - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(Int64ValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - SetSourcei64v(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!value) - alSetError(Context, AL_INVALID_VALUE); - else if(!(FloatValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALdouble dval; - if(GetSourcedv(Source, Context, param, &dval)) - *value = (ALfloat)dval; - } - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE); - else if(!(FloatValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals)) - { - *value1 = (ALfloat)dvals[0]; - *value2 = (ALfloat)dvals[1]; - *value3 = (ALfloat)dvals[2]; - } - } - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values) -{ - ALCcontext *Context; - ALsource *Source; - ALint count; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!((count=FloatValsByProp(param)) > 0 && count <= 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals)) - { - ALint i; - for(i = 0;i < count;i++) - values[i] = (ALfloat)dvals[i]; - } - } - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!value) - alSetError(Context, AL_INVALID_VALUE); - else if(!(DoubleValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourcedv(Source, Context, param, value); - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE); - else if(!(DoubleValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALdouble dvals[3]; - if(GetSourcedv(Source, Context, param, dvals)) - { - *value1 = dvals[0]; - *value2 = dvals[1]; - *value3 = dvals[2]; - } - } - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(DoubleValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourcedv(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!value) - alSetError(Context, AL_INVALID_VALUE); - else if(!(IntValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourceiv(Source, Context, param, value); - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE); - else if(!(IntValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALint ivals[3]; - if(GetSourceiv(Source, Context, param, ivals)) - { - *value1 = ivals[0]; - *value2 = ivals[1]; - *value3 = ivals[2]; - } - } - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(IntValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourceiv(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!value) - alSetError(Context, AL_INVALID_VALUE); - else if(!(Int64ValsByProp(param) == 1)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourcei64v(Source, Context, param, value); - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!(value1 && value2 && value3)) - alSetError(Context, AL_INVALID_VALUE); - else if(!(Int64ValsByProp(param) == 3)) - alSetError(Context, AL_INVALID_ENUM); - else - { - ALint64 i64vals[3]; - if(GetSourcei64v(Source, Context, param, i64vals)) - { - *value1 = i64vals[0]; - *value2 = i64vals[1]; - *value3 = i64vals[2]; - } - } - - ALCcontext_DecRef(Context); -} - -AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values) -{ - ALCcontext *Context; - ALsource *Source; - - Context = GetContextRef(); - if(!Context) return; - - if((Source=LookupSource(Context, source)) == NULL) - alSetError(Context, AL_INVALID_NAME); - else if(!values) - alSetError(Context, AL_INVALID_VALUE); - else if(!(Int64ValsByProp(param) > 0)) - alSetError(Context, AL_INVALID_ENUM); - else - GetSourcei64v(Source, Context, param, values); - - ALCcontext_DecRef(Context); -} - - -AL_API ALvoid AL_APIENTRY alSourcePlay(ALuint source) -{ - alSourcePlayv(1, &source); -} -AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) -{ - ALCcontext *context; - ALsource *source; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - } - - LockContext(context); - while(n > context->MaxActiveSources-context->ActiveSourceCount) - { - ALactivesource **temp = NULL; - ALsizei newcount; - - newcount = context->MaxActiveSources << 1; - if(newcount > 0) - temp = realloc(context->ActiveSources, - newcount * sizeof(context->ActiveSources[0])); - if(!temp) - { - UnlockContext(context); - SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done); - } - for(i = context->MaxActiveSources;i < newcount;i++) - temp[i] = NULL; - - context->ActiveSources = temp; - context->MaxActiveSources = newcount; - } - - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PLAYING; - else SetSourceState(source, context, AL_PLAYING); - } - UnlockContext(context); - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alSourcePause(ALuint source) -{ - alSourcePausev(1, &source); -} -AL_API ALvoid AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) -{ - ALCcontext *context; - ALsource *source; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - } - - LockContext(context); - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - if(context->DeferUpdates) source->new_state = AL_PAUSED; - else SetSourceState(source, context, AL_PAUSED); - } - UnlockContext(context); - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alSourceStop(ALuint source) -{ - alSourceStopv(1, &source); -} -AL_API ALvoid AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) -{ - ALCcontext *context; - ALsource *source; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - } - - LockContext(context); - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - source->new_state = AL_NONE; - SetSourceState(source, context, AL_STOPPED); - } - UnlockContext(context); - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alSourceRewind(ALuint source) -{ - alSourceRewindv(1, &source); -} -AL_API ALvoid AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) -{ - ALCcontext *context; - ALsource *source; - ALsizei i; - - context = GetContextRef(); - if(!context) return; - - if(!(n >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - for(i = 0;i < n;i++) - { - if(!LookupSource(context, sources[i])) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - } - - LockContext(context); - for(i = 0;i < n;i++) - { - source = LookupSource(context, sources[i]); - source->new_state = AL_NONE; - SetSourceState(source, context, AL_INITIAL); - } - UnlockContext(context); - -done: - ALCcontext_DecRef(context); -} - - -AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALuint *buffers) -{ - ALCdevice *device; - ALCcontext *context; - ALsource *source; - ALsizei i; - ALbufferlistitem *BufferListStart; - ALbufferlistitem *BufferList; - ALbuffer *BufferFmt = NULL; - - if(nb == 0) - return; - - context = GetContextRef(); - if(!context) return; - - device = context->Device; - - if(!(nb >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - if((source=LookupSource(context, src)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - - WriteLock(&source->queue_lock); - if(source->SourceType == AL_STATIC) - { - WriteUnlock(&source->queue_lock); - /* Can't queue on a Static Source */ - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done); - } - - /* Check for a valid Buffer, for its frequency and format */ - BufferList = ATOMIC_LOAD(&source->queue); - while(BufferList) - { - if(BufferList->buffer) - { - BufferFmt = BufferList->buffer; - break; - } - BufferList = BufferList->next; - } - - BufferListStart = NULL; - BufferList = NULL; - for(i = 0;i < nb;i++) - { - ALbuffer *buffer = NULL; - if(buffers[i] && (buffer=LookupBuffer(device, buffers[i])) == NULL) - { - WriteUnlock(&source->queue_lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, buffer_error); - } - - if(!BufferListStart) - { - BufferListStart = malloc(sizeof(ALbufferlistitem)); - BufferListStart->buffer = buffer; - BufferListStart->next = NULL; - BufferListStart->prev = NULL; - BufferList = BufferListStart; - } - else - { - BufferList->next = malloc(sizeof(ALbufferlistitem)); - BufferList->next->buffer = buffer; - BufferList->next->next = NULL; - BufferList->next->prev = BufferList; - BufferList = BufferList->next; - } - if(!buffer) continue; - - /* Hold a read lock on each buffer being queued while checking all - * provided buffers. This is done so other threads don't see an extra - * reference on some buffers if this operation ends up failing. */ - ReadLock(&buffer->lock); - IncrementRef(&buffer->ref); - - if(BufferFmt == NULL) - { - BufferFmt = buffer; - - source->NumChannels = ChannelsFromFmt(buffer->FmtChannels); - source->SampleSize = BytesFromFmt(buffer->FmtType); - } - else if(BufferFmt->Frequency != buffer->Frequency || - BufferFmt->OriginalChannels != buffer->OriginalChannels || - BufferFmt->OriginalType != buffer->OriginalType) - { - WriteUnlock(&source->queue_lock); - SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, buffer_error); - - buffer_error: - /* A buffer failed (invalid ID or format), so unlock and release - * each buffer we had. */ - while(BufferList != NULL) - { - ALbufferlistitem *prev = BufferList->prev; - if((buffer=BufferList->buffer) != NULL) - { - DecrementRef(&buffer->ref); - ReadUnlock(&buffer->lock); - } - free(BufferList); - BufferList = prev; - } - goto done; - } - } - /* All buffers good, unlock them now. */ - while(BufferList != NULL) - { - ALbuffer *buffer = BufferList->buffer; - if(buffer) ReadUnlock(&buffer->lock); - BufferList = BufferList->prev; - } - - /* Source is now streaming */ - source->SourceType = AL_STREAMING; - - BufferList = NULL; - if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->queue, &BufferList, BufferListStart)) - { - /* Queue head is not NULL, append to the end of the queue */ - while(BufferList->next != NULL) - BufferList = BufferList->next; - - BufferListStart->prev = BufferList; - BufferList->next = BufferListStart; - } - BufferList = NULL; - ATOMIC_COMPARE_EXCHANGE_STRONG(ALbufferlistitem*, &source->current_buffer, &BufferList, BufferListStart); - WriteUnlock(&source->queue_lock); - -done: - ALCcontext_DecRef(context); -} - -AL_API ALvoid AL_APIENTRY alSourceUnqueueBuffers(ALuint src, ALsizei nb, ALuint *buffers) -{ - ALCcontext *context; - ALsource *source; - ALbufferlistitem *NewHead; - ALbufferlistitem *OldHead; - ALbufferlistitem *Current; - ALsizei i; - - if(nb == 0) - return; - - context = GetContextRef(); - if(!context) return; - - if(!(nb >= 0)) - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - - if((source=LookupSource(context, src)) == NULL) - SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done); - - WriteLock(&source->queue_lock); - /* Find the new buffer queue head */ - NewHead = ATOMIC_LOAD(&source->queue); - Current = ATOMIC_LOAD(&source->current_buffer); - for(i = 0;i < nb && NewHead;i++) - { - if(NewHead == Current) - break; - NewHead = NewHead->next; - } - if(source->Looping || source->SourceType != AL_STREAMING || i != nb) - { - WriteUnlock(&source->queue_lock); - /* Trying to unqueue pending buffers, or a buffer that wasn't queued. */ - SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done); - } - - /* Swap it, and cut the new head from the old. */ - OldHead = ATOMIC_EXCHANGE(ALbufferlistitem*, &source->queue, NewHead); - if(NewHead) - { - ALCdevice *device = context->Device; - ALbufferlistitem *OldTail = NewHead->prev; - uint count; - - /* Cut the new head's link back to the old body. The mixer is robust - * enough to handle the link back going away. Once the active mix (if - * any) is complete, it's safe to finish cutting the old tail from the - * new head. */ - NewHead->prev = NULL; - if(((count=ReadRef(&device->MixCount))&1) != 0) - { - while(count == ReadRef(&device->MixCount)) - althrd_yield(); - } - OldTail->next = NULL; - } - WriteUnlock(&source->queue_lock); - - while(OldHead != NULL) - { - ALbufferlistitem *next = OldHead->next; - ALbuffer *buffer = OldHead->buffer; - - if(!buffer) - *(buffers++) = 0; - else - { - *(buffers++) = buffer->id; - DecrementRef(&buffer->ref); - } - - free(OldHead); - OldHead = next; - } - -done: - ALCcontext_DecRef(context); -} - - -static ALvoid InitSourceParams(ALsource *Source) -{ - ALuint i; - - RWLockInit(&Source->queue_lock); - - Source->InnerAngle = 360.0f; - Source->OuterAngle = 360.0f; - Source->Pitch = 1.0f; - Source->Position[0] = 0.0f; - Source->Position[1] = 0.0f; - Source->Position[2] = 0.0f; - Source->Orientation[0] = 0.0f; - Source->Orientation[1] = 0.0f; - Source->Orientation[2] = 0.0f; - Source->Velocity[0] = 0.0f; - Source->Velocity[1] = 0.0f; - Source->Velocity[2] = 0.0f; - Source->RefDistance = 1.0f; - Source->MaxDistance = FLT_MAX; - Source->RollOffFactor = 1.0f; - Source->Looping = AL_FALSE; - Source->Gain = 1.0f; - Source->MinGain = 0.0f; - Source->MaxGain = 1.0f; - Source->OuterGain = 0.0f; - Source->OuterGainHF = 1.0f; - - Source->DryGainHFAuto = AL_TRUE; - Source->WetGainAuto = AL_TRUE; - Source->WetGainHFAuto = AL_TRUE; - Source->AirAbsorptionFactor = 0.0f; - Source->RoomRolloffFactor = 0.0f; - Source->DopplerFactor = 1.0f; - Source->DirectChannels = AL_FALSE; - - Source->Radius = 0.0f; - - Source->DistanceModel = DefaultDistanceModel; - - Source->Resampler = DefaultResampler; - - Source->state = AL_INITIAL; - Source->new_state = AL_NONE; - Source->SourceType = AL_UNDETERMINED; - Source->Offset = -1.0; - - ATOMIC_INIT(&Source->queue, NULL); - ATOMIC_INIT(&Source->current_buffer, NULL); - - Source->Direct.Gain = 1.0f; - Source->Direct.GainHF = 1.0f; - Source->Direct.HFReference = LOWPASSFREQREF; - Source->Direct.GainLF = 1.0f; - Source->Direct.LFReference = HIGHPASSFREQREF; - for(i = 0;i < MAX_SENDS;i++) - { - Source->Send[i].Gain = 1.0f; - Source->Send[i].GainHF = 1.0f; - Source->Send[i].HFReference = LOWPASSFREQREF; - Source->Send[i].GainLF = 1.0f; - Source->Send[i].LFReference = HIGHPASSFREQREF; - } - - ATOMIC_INIT(&Source->NeedsUpdate, AL_TRUE); -} - - -/* SetSourceState - * - * Sets the source's new play state given its current state. - */ -ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state) -{ - ReadLock(&Source->queue_lock); - if(state == AL_PLAYING) - { - ALCdevice *device = Context->Device; - ALbufferlistitem *BufferList; - ALactivesource *src = NULL; - ALsizei j, k; - - /* Check that there is a queue containing at least one valid, non zero - * length Buffer. */ - BufferList = ATOMIC_LOAD(&Source->queue); - while(BufferList) - { - ALbuffer *buffer; - if((buffer=BufferList->buffer) != NULL && buffer->SampleLen > 0) - break; - BufferList = BufferList->next; - } - - if(Source->state != AL_PAUSED) - { - Source->state = AL_PLAYING; - Source->position = 0; - Source->position_fraction = 0; - ATOMIC_STORE(&Source->current_buffer, BufferList); - } - else - Source->state = AL_PLAYING; - - // Check if an Offset has been set - if(Source->Offset >= 0.0) - ApplyOffset(Source); - - /* If there's nothing to play, or device is disconnected, go right to - * stopped */ - if(!BufferList || !device->Connected) - goto do_stop; - - for(j = 0;j < Context->ActiveSourceCount;j++) - { - if(Context->ActiveSources[j]->Source == Source) - { - src = Context->ActiveSources[j]; - break; - } - } - if(src == NULL) - { - src = Context->ActiveSources[Context->ActiveSourceCount]; - if(src == NULL) - { - src = al_malloc(16, sizeof(src[0])); - Context->ActiveSources[Context->ActiveSourceCount] = src; - } - memset(src, 0, sizeof(*src)); - Context->ActiveSourceCount++; - - src->Source = Source; - } - else - { - ALuint i; - - src->Direct.Moving = AL_FALSE; - src->Direct.Counter = 0; - for(j = 0;j < MAX_INPUT_CHANNELS;j++) - { - for(k = 0;k < SRC_HISTORY_LENGTH;k++) - src->Direct.Mix.Hrtf.State[j].History[k] = 0.0f; - for(k = 0;k < HRIR_LENGTH;k++) - { - src->Direct.Mix.Hrtf.State[j].Values[k][0] = 0.0f; - src->Direct.Mix.Hrtf.State[j].Values[k][1] = 0.0f; - } - } - for(i = 0;i < device->NumAuxSends;i++) - { - src->Send[i].Counter = 0; - src->Send[i].Moving = AL_FALSE; - } - } - - if(BufferList->buffer->FmtChannels == FmtMono) - src->Update = CalcSourceParams; - else - src->Update = CalcNonAttnSourceParams; - - ATOMIC_STORE(&Source->NeedsUpdate, AL_TRUE); - } - else if(state == AL_PAUSED) - { - if(Source->state == AL_PLAYING) - Source->state = AL_PAUSED; - } - else if(state == AL_STOPPED) - { - do_stop: - if(Source->state != AL_INITIAL) - { - Source->state = AL_STOPPED; - ATOMIC_STORE(&Source->current_buffer, NULL); - } - Source->Offset = -1.0; - } - else if(state == AL_INITIAL) - { - if(Source->state != AL_INITIAL) - { - Source->state = AL_INITIAL; - Source->position = 0; - Source->position_fraction = 0; - ATOMIC_STORE(&Source->current_buffer, ATOMIC_LOAD(&Source->queue)); - } - Source->Offset = -1.0; - } - ReadUnlock(&Source->queue_lock); -} - -/* GetSourceOffset - * - * Gets the current read offset for the given Source, in 32.32 fixed-point - * samples. The offset is relative to the start of the queue (not the start of - * the current buffer). - */ -static ALint64 GetSourceOffset(const ALsource *Source) -{ - const ALbufferlistitem *BufferList; - const ALbufferlistitem *Current; - ALuint64 readPos; - - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) - return 0; - - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ - readPos = (ALuint64)Source->position << 32; - readPos |= (ALuint64)Source->position_fraction << (32-FRACTIONBITS); - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); - while(BufferList && BufferList != Current) - { - if(BufferList->buffer) - readPos += (ALuint64)BufferList->buffer->SampleLen << 32; - BufferList = BufferList->next; - } - - return (ALint64)minu64(readPos, U64(0x7fffffffffffffff)); -} - -/* GetSourceSecOffset - * - * Gets the current read offset for the given Source, in seconds. The offset is - * relative to the start of the queue (not the start of the current buffer). - */ -static ALdouble GetSourceSecOffset(const ALsource *Source) -{ - const ALbufferlistitem *BufferList; - const ALbufferlistitem *Current; - const ALbuffer *Buffer = NULL; - ALuint64 readPos; - - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) - return 0.0; - - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ - readPos = (ALuint64)Source->position << FRACTIONBITS; - readPos |= (ALuint64)Source->position_fraction; - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); - while(BufferList && BufferList != Current) - { - const ALbuffer *buffer = BufferList->buffer; - if(buffer != NULL) - { - if(!Buffer) Buffer = buffer; - readPos += (ALuint64)buffer->SampleLen << FRACTIONBITS; - } - BufferList = BufferList->next; - } - - while(BufferList && !Buffer) - { - Buffer = BufferList->buffer; - BufferList = BufferList->next; - } - assert(Buffer != NULL); - - return (ALdouble)readPos / (ALdouble)FRACTIONONE / (ALdouble)Buffer->Frequency; -} - -/* GetSourceOffsets - * - * Gets the current read and write offsets for the given Source, in the - * appropriate format (Bytes, Samples or Seconds). The offsets are relative to - * the start of the queue (not the start of the current buffer). - */ -static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *offset, ALdouble updateLen) -{ - const ALbufferlistitem *BufferList; - const ALbufferlistitem *Current; - const ALbuffer *Buffer = NULL; - ALboolean readFin = AL_FALSE; - ALuint readPos, writePos; - ALuint totalBufferLen; - - if(Source->state != AL_PLAYING && Source->state != AL_PAUSED) - { - offset[0] = 0.0; - offset[1] = 0.0; - return; - } - - if(updateLen > 0.0 && updateLen < 0.015) - updateLen = 0.015; - - /* NOTE: This is the offset into the *current* buffer, so add the length of - * any played buffers */ - totalBufferLen = 0; - readPos = Source->position; - BufferList = ATOMIC_LOAD(&Source->queue); - Current = ATOMIC_LOAD(&Source->current_buffer); - while(BufferList != NULL) - { - const ALbuffer *buffer; - readFin = readFin || (BufferList == Current); - if((buffer=BufferList->buffer) != NULL) - { - if(!Buffer) Buffer = buffer; - totalBufferLen += buffer->SampleLen; - if(!readFin) readPos += buffer->SampleLen; - } - BufferList = BufferList->next; - } - assert(Buffer != NULL); - - if(Source->state == AL_PLAYING) - writePos = readPos + (ALuint)(updateLen*Buffer->Frequency); - else - writePos = readPos; - - if(Source->Looping) - { - readPos %= totalBufferLen; - writePos %= totalBufferLen; - } - else - { - /* Wrap positions back to 0 */ - if(readPos >= totalBufferLen) - readPos = 0; - if(writePos >= totalBufferLen) - writePos = 0; - } - - switch(name) - { - case AL_SEC_OFFSET: - offset[0] = (ALdouble)readPos / Buffer->Frequency; - offset[1] = (ALdouble)writePos / Buffer->Frequency; - break; - - case AL_SAMPLE_OFFSET: - case AL_SAMPLE_RW_OFFSETS_SOFT: - offset[0] = (ALdouble)readPos; - offset[1] = (ALdouble)writePos; - break; - - case AL_BYTE_OFFSET: - case AL_BYTE_RW_OFFSETS_SOFT: - if(Buffer->OriginalType == UserFmtIMA4) - { - ALsizei align = (Buffer->OriginalAlign-1)/2 + 4; - ALuint BlockSize = align * ChannelsFromFmt(Buffer->FmtChannels); - ALuint FrameBlockSize = Buffer->OriginalAlign; - - /* Round down to nearest ADPCM block */ - offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize); - if(Source->state != AL_PLAYING) - offset[1] = offset[0]; - else - { - /* Round up to nearest ADPCM block */ - offset[1] = (ALdouble)((writePos+FrameBlockSize-1) / - FrameBlockSize * BlockSize); - } - } - else if(Buffer->OriginalType == UserFmtMSADPCM) - { - ALsizei align = (Buffer->OriginalAlign-2)/2 + 7; - ALuint BlockSize = align * ChannelsFromFmt(Buffer->FmtChannels); - ALuint FrameBlockSize = Buffer->OriginalAlign; - - /* Round down to nearest ADPCM block */ - offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize); - if(Source->state != AL_PLAYING) - offset[1] = offset[0]; - else - { - /* Round up to nearest ADPCM block */ - offset[1] = (ALdouble)((writePos+FrameBlockSize-1) / - FrameBlockSize * BlockSize); - } - } - else - { - ALuint FrameSize = FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType); - offset[0] = (ALdouble)(readPos * FrameSize); - offset[1] = (ALdouble)(writePos * FrameSize); - } - break; - } -} - - -/* ApplyOffset - * - * Apply the stored playback offset to the Source. This function will update - * the number of buffers "played" given the stored offset. - */ -ALboolean ApplyOffset(ALsource *Source) -{ - ALbufferlistitem *BufferList; - const ALbuffer *Buffer; - ALint bufferLen, totalBufferLen; - ALint offset; - - /* Get sample frame offset */ - offset = GetSampleOffset(Source); - if(offset == -1) - return AL_FALSE; - - totalBufferLen = 0; - BufferList = ATOMIC_LOAD(&Source->queue); - while(BufferList && totalBufferLen <= offset) - { - Buffer = BufferList->buffer; - bufferLen = Buffer ? Buffer->SampleLen : 0; - - if(bufferLen > offset-totalBufferLen) - { - /* Offset is in this buffer */ - ATOMIC_STORE(&Source->current_buffer, BufferList); - - Source->position = offset - totalBufferLen; - Source->position_fraction = 0; - return AL_TRUE; - } - - totalBufferLen += bufferLen; - - BufferList = BufferList->next; - } - - /* Offset is out of range of the queue */ - return AL_FALSE; -} - - -/* GetSampleOffset - * - * Returns the sample offset into the Source's queue (from the Sample, Byte or - * Second offset supplied by the application). This takes into account the fact - * that the buffer format may have been modifed since. - */ -static ALint GetSampleOffset(ALsource *Source) -{ - const ALbuffer *Buffer = NULL; - const ALbufferlistitem *BufferList; - ALint Offset = -1; - - /* Find the first valid Buffer in the Queue */ - BufferList = ATOMIC_LOAD(&Source->queue); - while(BufferList) - { - if(BufferList->buffer) - { - Buffer = BufferList->buffer; - break; - } - BufferList = BufferList->next; - } - - if(!Buffer) - { - Source->Offset = -1.0; - return -1; - } - - switch(Source->OffsetType) - { - case AL_BYTE_OFFSET: - /* Determine the ByteOffset (and ensure it is block aligned) */ - Offset = (ALint)Source->Offset; - if(Buffer->OriginalType == UserFmtIMA4) - { - ALsizei align = (Buffer->OriginalAlign-1)/2 + 4; - Offset /= align * ChannelsFromUserFmt(Buffer->OriginalChannels); - Offset *= Buffer->OriginalAlign; - } - else if(Buffer->OriginalType == UserFmtMSADPCM) - { - ALsizei align = (Buffer->OriginalAlign-2)/2 + 7; - Offset /= align * ChannelsFromUserFmt(Buffer->OriginalChannels); - Offset *= Buffer->OriginalAlign; - } - else - Offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType); - break; - - case AL_SAMPLE_OFFSET: - Offset = (ALint)Source->Offset; - break; - - case AL_SEC_OFFSET: - Offset = (ALint)(Source->Offset * Buffer->Frequency); - break; - } - Source->Offset = -1.0; - - return Offset; -} - - -/* ReleaseALSources - * - * Destroys all sources in the source map. - */ -ALvoid ReleaseALSources(ALCcontext *Context) -{ - ALbufferlistitem *item; - ALsizei pos; - ALuint j; - for(pos = 0;pos < Context->SourceMap.size;pos++) - { - ALsource *temp = Context->SourceMap.array[pos].value; - Context->SourceMap.array[pos].value = NULL; - - item = ATOMIC_EXCHANGE(ALbufferlistitem*, &temp->queue, NULL); - while(item != NULL) - { - ALbufferlistitem *next = item->next; - if(item->buffer != NULL) - DecrementRef(&item->buffer->ref); - free(item); - item = next; - } - - for(j = 0;j < MAX_SENDS;++j) - { - if(temp->Send[j].Slot) - DecrementRef(&temp->Send[j].Slot->ref); - temp->Send[j].Slot = NULL; - } - - FreeThunkEntry(temp->id); - memset(temp, 0, sizeof(*temp)); - al_free(temp); - } -} diff --git a/love/src/jni/openal-soft-1.17.0/build/.empty b/love/src/jni/openal-soft-1.17.0/build/.empty deleted file mode 100644 index e69de29b..00000000 diff --git a/love/src/jni/openal-soft-1.17.0/cmake/FindDSound.cmake b/love/src/jni/openal-soft-1.17.0/cmake/FindDSound.cmake deleted file mode 100644 index 36cdf4b5..00000000 --- a/love/src/jni/openal-soft-1.17.0/cmake/FindDSound.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# - Find DirectSound includes and libraries -# -# DSOUND_FOUND - True if DSOUND_INCLUDE_DIR & DSOUND_LIBRARY are found -# DSOUND_LIBRARIES - Set when DSOUND_LIBRARY is found -# DSOUND_INCLUDE_DIRS - Set when DSOUND_INCLUDE_DIR is found -# -# DSOUND_INCLUDE_DIR - where to find dsound.h, etc. -# DSOUND_LIBRARY - the dsound library -# - -find_path(DSOUND_INCLUDE_DIR - PATHS "${DXSDK_DIR}/include" - NAMES dsound.h - DOC "The DirectSound include directory" -) - -find_library(DSOUND_LIBRARY - PATHS "${DXSDK_DIR}/lib" - NAMES dsound - DOC "The DirectSound library" -) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(DSound - REQUIRED_VARS DSOUND_LIBRARY DSOUND_INCLUDE_DIR -) - -if(DSOUND_FOUND) - set(DSOUND_LIBRARIES ${DSOUND_LIBRARY}) - set(DSOUND_INCLUDE_DIRS ${DSOUND_INCLUDE_DIR}) -endif() - -mark_as_advanced(DSOUND_INCLUDE_DIR DSOUND_LIBRARY) diff --git a/love/src/jni/openal-soft-1.17.0/cmake/FindFluidSynth.cmake b/love/src/jni/openal-soft-1.17.0/cmake/FindFluidSynth.cmake deleted file mode 100644 index fe96b225..00000000 --- a/love/src/jni/openal-soft-1.17.0/cmake/FindFluidSynth.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# - Find fluidsynth -# Find the native fluidsynth includes and library -# -# FLUIDSYNTH_INCLUDE_DIR - where to find fluidsynth.h -# FLUIDSYNTH_LIBRARIES - List of libraries when using fluidsynth. -# FLUIDSYNTH_FOUND - True if fluidsynth found. - - -FIND_PATH(FLUIDSYNTH_INCLUDE_DIR fluidsynth.h) - -FIND_LIBRARY(FLUIDSYNTH_LIBRARIES NAMES fluidsynth ) -MARK_AS_ADVANCED( FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR ) - -# handle the QUIETLY and REQUIRED arguments and set FLUIDSYNTH_FOUND to TRUE if -# all listed variables are TRUE -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(FluidSynth - REQUIRED_VARS FLUIDSYNTH_LIBRARIES FLUIDSYNTH_INCLUDE_DIR) - diff --git a/love/src/jni/openal-soft-1.17.0/cmake/FindSDL_sound.cmake b/love/src/jni/openal-soft-1.17.0/cmake/FindSDL_sound.cmake deleted file mode 100644 index 2dab1a1c..00000000 --- a/love/src/jni/openal-soft-1.17.0/cmake/FindSDL_sound.cmake +++ /dev/null @@ -1,380 +0,0 @@ -# - Locates the SDL_sound library -# -# This module depends on SDL being found and -# must be called AFTER FindSDL.cmake or FindSDL2.cmake is called. -# -# This module defines -# SDL_SOUND_INCLUDE_DIR, where to find SDL_sound.h -# SDL_SOUND_FOUND, if false, do not try to link to SDL_sound -# SDL_SOUND_LIBRARIES, this contains the list of libraries that you need -# to link against. This is a read-only variable and is marked INTERNAL. -# SDL_SOUND_EXTRAS, this is an optional variable for you to add your own -# flags to SDL_SOUND_LIBRARIES. This is prepended to SDL_SOUND_LIBRARIES. -# This is available mostly for cases this module failed to anticipate for -# and you must add additional flags. This is marked as ADVANCED. -# SDL_SOUND_VERSION_STRING, human-readable string containing the version of SDL_sound -# -# This module also defines (but you shouldn't need to use directly) -# SDL_SOUND_LIBRARY, the name of just the SDL_sound library you would link -# against. Use SDL_SOUND_LIBRARIES for you link instructions and not this one. -# And might define the following as needed -# MIKMOD_LIBRARY -# MODPLUG_LIBRARY -# OGG_LIBRARY -# VORBIS_LIBRARY -# SMPEG_LIBRARY -# FLAC_LIBRARY -# SPEEX_LIBRARY -# -# Typically, you should not use these variables directly, and you should use -# SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other audio libraries -# (if needed) to successfully compile on your system. -# -# Created by Eric Wing. -# This module is a bit more complicated than the other FindSDL* family modules. -# The reason is that SDL_sound can be compiled in a large variety of different ways -# which are independent of platform. SDL_sound may dynamically link against other 3rd -# party libraries to get additional codec support, such as Ogg Vorbis, SMPEG, ModPlug, -# MikMod, FLAC, Speex, and potentially others. -# Under some circumstances which I don't fully understand, -# there seems to be a requirement -# that dependent libraries of libraries you use must also be explicitly -# linked against in order to successfully compile. SDL_sound does not currently -# have any system in place to know how it was compiled. -# So this CMake module does the hard work in trying to discover which 3rd party -# libraries are required for building (if any). -# This module uses a brute force approach to create a test program that uses SDL_sound, -# and then tries to build it. If the build fails, it parses the error output for -# known symbol names to figure out which libraries are needed. -# -# Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that would -# correspond to the ./configure --prefix=$SDLDIR used in building SDL. -# -# On OSX, this will prefer the Framework version (if found) over others. -# People will have to manually change the cache values of -# SDL_LIBRARY or SDL2_LIBRARY to override this selection or set the CMake -# environment CMAKE_INCLUDE_PATH to modify the search paths. - -#============================================================================= -# Copyright 2005-2009 Kitware, Inc. -# Copyright 2012 Benjamin Eikel -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) - -set(SDL_SOUND_EXTRAS "" CACHE STRING "SDL_sound extra flags") -mark_as_advanced(SDL_SOUND_EXTRAS) - -# Find SDL_sound.h -find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h - HINTS - ENV SDLSOUNDDIR - ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 -) - -find_library(SDL_SOUND_LIBRARY - NAMES SDL_sound - HINTS - ENV SDLSOUNDDIR - ENV SDLDIR -) - -if(SDL2_FOUND OR SDL_FOUND) - if(SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) - # CMake is giving me problems using TRY_COMPILE with the CMAKE_FLAGS - # for the :STRING syntax if I have multiple values contained in a - # single variable. This is a problem for the SDL2_LIBRARY variable - # because it does just that. When I feed this variable to the command, - # only the first value gets the appropriate modifier (e.g. -I) and - # the rest get dropped. - # To get multiple single variables to work, I must separate them with a "\;" - # I could go back and modify the FindSDL2.cmake module, but that's kind of painful. - # The solution would be to try something like: - # set(SDL2_TRY_COMPILE_LIBRARY_LIST "${SDL2_TRY_COMPILE_LIBRARY_LIST}\;${CMAKE_THREAD_LIBS_INIT}") - # Instead, it was suggested on the mailing list to write a temporary CMakeLists.txt - # with a temporary test project and invoke that with TRY_COMPILE. - # See message thread "Figuring out dependencies for a library in order to build" - # 2005-07-16 - # try_compile( - # MY_RESULT - # ${CMAKE_BINARY_DIR} - # ${PROJECT_SOURCE_DIR}/DetermineSoundLibs.c - # CMAKE_FLAGS - # -DINCLUDE_DIRECTORIES:STRING=${SDL2_INCLUDE_DIR}\;${SDL_SOUND_INCLUDE_DIR} - # -DLINK_LIBRARIES:STRING=${SDL_SOUND_LIBRARY}\;${SDL2_LIBRARY} - # OUTPUT_VARIABLE MY_OUTPUT - # ) - - # To minimize external dependencies, create a sdlsound test program - # which will be used to figure out if additional link dependencies are - # required for the link phase. - file(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/DetermineSoundLibs.c - "#include \"SDL_sound.h\" - #include \"SDL.h\" - int main(int argc, char* argv[]) - { - Sound_AudioInfo desired; - Sound_Sample* sample; - - SDL_Init(0); - Sound_Init(); - - /* This doesn't actually have to work, but Init() is a no-op - * for some of the decoders, so this should force more symbols - * to be pulled in. - */ - sample = Sound_NewSampleFromFile(argv[1], &desired, 4096); - - Sound_Quit(); - SDL_Quit(); - return 0; - }" - ) - - # Calling - # target_link_libraries(DetermineSoundLibs "${SDL_SOUND_LIBRARY} ${SDL2_LIBRARY}) - # causes problems when SDL2_LIBRARY looks like - # /Library/Frameworks/SDL2.framework;-framework Cocoa - # The ;-framework Cocoa seems to be confusing CMake once the OS X - # framework support was added. I was told that breaking up the list - # would fix the problem. - set(TMP_TRY_LIBS) - if(SDL2_FOUND) - foreach(lib ${SDL_SOUND_LIBRARY} ${SDL2_LIBRARY}) - set(TMP_TRY_LIBS "${TMP_TRY_LIBS} \"${lib}\"") - endforeach() - set(TMP_INCLUDE_DIRS ${SDL2_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR}) - else() - foreach(lib ${SDL_SOUND_LIBRARY} ${SDL_LIBRARY}) - set(TMP_TRY_LIBS "${TMP_TRY_LIBS} \"${lib}\"") - endforeach() - set(TMP_INCLUDE_DIRS ${SDL_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR}) - endif() - - # message("TMP_TRY_LIBS ${TMP_TRY_LIBS}") - - # Write the CMakeLists.txt and test project - # Weird, this is still sketchy. If I don't quote the variables - # in the TARGET_LINK_LIBRARIES, I seem to loose everything - # in the SDL2_LIBRARY string after the "-framework". - # But if I quote the stuff in INCLUDE_DIRECTORIES, it doesn't work. - file(WRITE ${PROJECT_BINARY_DIR}/CMakeTmp/CMakeLists.txt - "cmake_minimum_required(VERSION 2.8) - project(DetermineSoundLibs C) - include_directories(${TMP_INCLUDE_DIRS}) - add_executable(DetermineSoundLibs DetermineSoundLibs.c) - target_link_libraries(DetermineSoundLibs ${TMP_TRY_LIBS})" - ) - unset(TMP_INCLUDE_DIRS) - unset(TMP_TRY_LIBS) - - try_compile( - MY_RESULT - ${PROJECT_BINARY_DIR}/CMakeTmp - ${PROJECT_BINARY_DIR}/CMakeTmp - DetermineSoundLibs - OUTPUT_VARIABLE MY_OUTPUT - ) - # message("${MY_RESULT}") - # message(${MY_OUTPUT}) - - if(NOT MY_RESULT) - # I expect that MPGLIB, VOC, WAV, AIFF, and SHN are compiled in statically. - # I think Timidity is also compiled in statically. - # I've never had to explcitly link against Quicktime, so I'll skip that for now. - - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARY}) - - # Find MikMod - if("${MY_OUTPUT}" MATCHES "MikMod_") - find_library(MIKMOD_LIBRARY - NAMES libmikmod-coreaudio mikmod - PATHS - ENV MIKMODDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(MIKMOD_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MIKMOD_LIBRARY}) - endif(MIKMOD_LIBRARY) - endif("${MY_OUTPUT}" MATCHES "MikMod_") - - # Find ModPlug - if("${MY_OUTPUT}" MATCHES "MODPLUG_") - find_library(MODPLUG_LIBRARY - NAMES modplug - PATHS - ENV MODPLUGDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(MODPLUG_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${MODPLUG_LIBRARY}) - endif() - endif() - - # Find Ogg and Vorbis - if("${MY_OUTPUT}" MATCHES "ov_") - find_library(VORBIS_LIBRARY - NAMES vorbis Vorbis VORBIS - PATHS - ENV VORBISDIR - ENV OGGDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(VORBIS_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${VORBIS_LIBRARY}) - endif() - find_library(OGG_LIBRARY - NAMES ogg Ogg OGG - PATHS - ENV OGGDIR - ENV VORBISDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(OGG_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY}) - endif() - endif() - - # Find SMPEG - if("${MY_OUTPUT}" MATCHES "SMPEG_") - find_library(SMPEG_LIBRARY - NAMES smpeg SMPEG Smpeg SMpeg - PATHS - ENV SMPEGDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(SMPEG_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SMPEG_LIBRARY}) - endif() - endif() - - - # Find FLAC - if("${MY_OUTPUT}" MATCHES "FLAC_") - find_library(FLAC_LIBRARY - NAMES flac FLAC - PATHS - ENV FLACDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(FLAC_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${FLAC_LIBRARY}) - endif() - endif() - - - # Hmmm...Speex seems to depend on Ogg. This might be a problem if - # the TRY_COMPILE attempt gets blocked at SPEEX before it can pull - # in the Ogg symbols. I'm not sure if I should duplicate the ogg stuff - # above for here or if two ogg entries will screw up things. - if("${MY_OUTPUT}" MATCHES "speex_") - find_library(SPEEX_LIBRARY - NAMES speex SPEEX - PATHS - ENV SPEEXDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(SPEEX_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${SPEEX_LIBRARY}) - endif() - - # Find OGG (needed for Speex) - # We might have already found Ogg for Vorbis, so skip it if so. - if(NOT OGG_LIBRARY) - find_library(OGG_LIBRARY - NAMES ogg Ogg OGG - PATHS - ENV OGGDIR - ENV VORBISDIR - ENV SPEEXDIR - ENV SDLSOUNDDIR - ENV SDLDIR - /sw - /opt/local - /opt/csw - /opt - PATH_SUFFIXES lib - ) - if(OGG_LIBRARY) - set(SDL_SOUND_LIBRARIES_TMP ${SDL_SOUND_LIBRARIES_TMP} ${OGG_LIBRARY}) - endif() - endif() - endif() - - set(SDL_SOUND_LIBRARIES ${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARIES_TMP} CACHE INTERNAL "SDL_sound and dependent libraries") - else() - set(SDL_SOUND_LIBRARIES ${SDL_SOUND_EXTRAS} ${SDL_SOUND_LIBRARY} CACHE INTERNAL "SDL_sound and dependent libraries") - endif() - endif() -endif() - -if(SDL_SOUND_INCLUDE_DIR AND EXISTS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h") - file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SOUND_VER_MAJOR[ \t]+[0-9]+$") - file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_MINOR_LINE REGEX "^#define[ \t]+SOUND_VER_MINOR[ \t]+[0-9]+$") - file(STRINGS "${SDL_SOUND_INCLUDE_DIR}/SDL_sound.h" SDL_SOUND_VERSION_PATCH_LINE REGEX "^#define[ \t]+SOUND_VER_PATCH[ \t]+[0-9]+$") - string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MAJOR "${SDL_SOUND_VERSION_MAJOR_LINE}") - string(REGEX REPLACE "^#define[ \t]+SOUND_VER_MINOR[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_MINOR "${SDL_SOUND_VERSION_MINOR_LINE}") - string(REGEX REPLACE "^#define[ \t]+SOUND_VER_PATCH[ \t]+([0-9]+)$" "\\1" SDL_SOUND_VERSION_PATCH "${SDL_SOUND_VERSION_PATCH_LINE}") - set(SDL_SOUND_VERSION_STRING ${SDL_SOUND_VERSION_MAJOR}.${SDL_SOUND_VERSION_MINOR}.${SDL_SOUND_VERSION_PATCH}) - unset(SDL_SOUND_VERSION_MAJOR_LINE) - unset(SDL_SOUND_VERSION_MINOR_LINE) - unset(SDL_SOUND_VERSION_PATCH_LINE) - unset(SDL_SOUND_VERSION_MAJOR) - unset(SDL_SOUND_VERSION_MINOR) - unset(SDL_SOUND_VERSION_PATCH) -endif() - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_sound - REQUIRED_VARS SDL_SOUND_LIBRARIES SDL_SOUND_INCLUDE_DIR - VERSION_VAR SDL_SOUND_VERSION_STRING) diff --git a/love/src/jni/openal-soft-1.17.0/common/uintmap.c b/love/src/jni/openal-soft-1.17.0/common/uintmap.c deleted file mode 100644 index b7a9a29c..00000000 --- a/love/src/jni/openal-soft-1.17.0/common/uintmap.c +++ /dev/null @@ -1,144 +0,0 @@ - -#include "config.h" - -#include "uintmap.h" - -#include -#include - - -extern inline void LockUIntMapRead(UIntMap *map); -extern inline void UnlockUIntMapRead(UIntMap *map); -extern inline void LockUIntMapWrite(UIntMap *map); -extern inline void UnlockUIntMapWrite(UIntMap *map); - - -void InitUIntMap(UIntMap *map, ALsizei limit) -{ - map->array = NULL; - map->size = 0; - map->maxsize = 0; - map->limit = limit; - RWLockInit(&map->lock); -} - -void ResetUIntMap(UIntMap *map) -{ - WriteLock(&map->lock); - free(map->array); - map->array = NULL; - map->size = 0; - map->maxsize = 0; - WriteUnlock(&map->lock); -} - -ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value) -{ - ALsizei pos = 0; - - WriteLock(&map->lock); - if(map->size > 0) - { - ALsizei low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key < key) - low++; - pos = low; - } - - if(pos == map->size || map->array[pos].key != key) - { - if(map->size == map->limit) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - - if(map->size == map->maxsize) - { - ALvoid *temp = NULL; - ALsizei newsize; - - newsize = (map->maxsize ? (map->maxsize<<1) : 4); - if(newsize >= map->maxsize) - temp = realloc(map->array, newsize*sizeof(map->array[0])); - if(!temp) - { - WriteUnlock(&map->lock); - return AL_OUT_OF_MEMORY; - } - map->array = temp; - map->maxsize = newsize; - } - - if(pos < map->size) - memmove(&map->array[pos+1], &map->array[pos], - (map->size-pos)*sizeof(map->array[0])); - map->size++; - } - map->array[pos].key = key; - map->array[pos].value = value; - WriteUnlock(&map->lock); - - return AL_NO_ERROR; -} - -ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key) -{ - ALvoid *ptr = NULL; - WriteLock(&map->lock); - if(map->size > 0) - { - ALsizei low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key == key) - { - ptr = map->array[low].value; - if(low < map->size-1) - memmove(&map->array[low], &map->array[low+1], - (map->size-1-low)*sizeof(map->array[0])); - map->size--; - } - } - WriteUnlock(&map->lock); - return ptr; -} - -ALvoid *LookupUIntMapKey(UIntMap *map, ALuint key) -{ - ALvoid *ptr = NULL; - ReadLock(&map->lock); - if(map->size > 0) - { - ALsizei low = 0; - ALsizei high = map->size - 1; - while(low < high) - { - ALsizei mid = low + (high-low)/2; - if(map->array[mid].key < key) - low = mid + 1; - else - high = mid; - } - if(map->array[low].key == key) - ptr = map->array[low].value; - } - ReadUnlock(&map->lock); - return ptr; -} diff --git a/love/src/jni/openal-soft-1.17.0/examples/alffplay.c b/love/src/jni/openal-soft-1.17.0/examples/alffplay.c deleted file mode 100644 index d8ef0e57..00000000 --- a/love/src/jni/openal-soft-1.17.0/examples/alffplay.c +++ /dev/null @@ -1,1479 +0,0 @@ -/* - * alffplay.c - * - * A pedagogical video player that really works! Now with seeking features. - * - * Code based on FFplay, Copyright (c) 2003 Fabrice Bellard, and a tutorial by - * Martin Bohme . - * - * Requires C99. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "threads.h" -#include "bool.h" - -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" - - -static bool has_latency_check = false; -static LPALGETSOURCEDVSOFT alGetSourcedvSOFT; - -#define AUDIO_BUFFER_TIME 100 /* In milliseconds, per-buffer */ -#define AUDIO_BUFFER_QUEUE_SIZE 8 /* Number of buffers to queue */ -#define MAX_AUDIOQ_SIZE (5 * 16 * 1024) /* Bytes of compressed audio data to keep queued */ -#define MAX_VIDEOQ_SIZE (5 * 256 * 1024) /* Bytes of compressed video data to keep queued */ -#define AV_SYNC_THRESHOLD 0.01 -#define AV_NOSYNC_THRESHOLD 10.0 -#define SAMPLE_CORRECTION_MAX_DIFF 0.1 -#define AUDIO_DIFF_AVG_NB 20 -#define VIDEO_PICTURE_QUEUE_SIZE 16 - -enum { - FF_UPDATE_EVENT = SDL_USEREVENT, - FF_REFRESH_EVENT, - FF_QUIT_EVENT -}; - - -typedef struct PacketQueue { - AVPacketList *first_pkt, *last_pkt; - volatile int nb_packets; - volatile int size; - volatile bool flushing; - almtx_t mutex; - alcnd_t cond; -} PacketQueue; - -typedef struct VideoPicture { - SDL_Texture *bmp; - int width, height; /* Logical image size (actual size may be larger) */ - volatile bool updated; - double pts; -} VideoPicture; - -typedef struct AudioState { - AVStream *st; - - PacketQueue q; - AVPacket pkt; - - /* Used for clock difference average computation */ - double diff_accum; - double diff_avg_coef; - double diff_threshold; - - /* Time (in seconds) of the next sample to be buffered */ - double current_pts; - - /* Decompressed sample frame, and swresample context for conversion */ - AVFrame *decoded_aframe; - struct SwrContext *swres_ctx; - - /* Conversion format, for what gets fed to OpenAL */ - int dst_ch_layout; - enum AVSampleFormat dst_sample_fmt; - - /* Storage of converted samples */ - uint8_t *samples; - ssize_t samples_len; /* In samples */ - ssize_t samples_pos; - int samples_max; - - /* OpenAL format */ - ALenum format; - ALint frame_size; - - ALuint source; - ALuint buffer[AUDIO_BUFFER_QUEUE_SIZE]; - ALuint buffer_idx; - almtx_t src_mutex; - - althrd_t thread; -} AudioState; - -typedef struct VideoState { - AVStream *st; - - PacketQueue q; - - double clock; - double frame_timer; - double frame_last_pts; - double frame_last_delay; - double current_pts; - /* time (av_gettime) at which we updated current_pts - used to have running video pts */ - int64_t current_pts_time; - - /* Decompressed video frame, and swscale context for conversion */ - AVFrame *decoded_vframe; - struct SwsContext *swscale_ctx; - - VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE]; - int pictq_size, pictq_rindex, pictq_windex; - almtx_t pictq_mutex; - alcnd_t pictq_cond; - - althrd_t thread; -} VideoState; - -typedef struct MovieState { - AVFormatContext *pFormatCtx; - int videoStream, audioStream; - - volatile bool seek_req; - int64_t seek_pos; - - int av_sync_type; - - int64_t external_clock_base; - - AudioState audio; - VideoState video; - - althrd_t parse_thread; - - char filename[1024]; - - volatile bool quit; -} MovieState; - -enum { - AV_SYNC_AUDIO_MASTER, - AV_SYNC_VIDEO_MASTER, - AV_SYNC_EXTERNAL_MASTER, - - DEFAULT_AV_SYNC_TYPE = AV_SYNC_EXTERNAL_MASTER -}; - -static AVPacket flush_pkt = { .data = (uint8_t*)"FLUSH" }; - -static void packet_queue_init(PacketQueue *q) -{ - memset(q, 0, sizeof(PacketQueue)); - almtx_init(&q->mutex, almtx_plain); - alcnd_init(&q->cond); -} -static int packet_queue_put(PacketQueue *q, AVPacket *pkt) -{ - AVPacketList *pkt1; - if(pkt != &flush_pkt && !pkt->buf && av_dup_packet(pkt) < 0) - return -1; - - pkt1 = av_malloc(sizeof(AVPacketList)); - if(!pkt1) return -1; - pkt1->pkt = *pkt; - pkt1->next = NULL; - - almtx_lock(&q->mutex); - if(!q->last_pkt) - q->first_pkt = pkt1; - else - q->last_pkt->next = pkt1; - q->last_pkt = pkt1; - q->nb_packets++; - q->size += pkt1->pkt.size; - almtx_unlock(&q->mutex); - - alcnd_signal(&q->cond); - return 0; -} -static int packet_queue_get(PacketQueue *q, AVPacket *pkt, MovieState *state) -{ - AVPacketList *pkt1; - int ret = -1; - - almtx_lock(&q->mutex); - while(!state->quit) - { - pkt1 = q->first_pkt; - if(pkt1) - { - q->first_pkt = pkt1->next; - if(!q->first_pkt) - q->last_pkt = NULL; - q->nb_packets--; - q->size -= pkt1->pkt.size; - *pkt = pkt1->pkt; - av_free(pkt1); - ret = 1; - break; - } - - if(q->flushing) - { - ret = 0; - break; - } - alcnd_wait(&q->cond, &q->mutex); - } - almtx_unlock(&q->mutex); - return ret; -} -static void packet_queue_clear(PacketQueue *q) -{ - AVPacketList *pkt, *pkt1; - - almtx_lock(&q->mutex); - for(pkt = q->first_pkt;pkt != NULL;pkt = pkt1) - { - pkt1 = pkt->next; - if(pkt->pkt.data != flush_pkt.data) - av_free_packet(&pkt->pkt); - av_freep(&pkt); - } - q->last_pkt = NULL; - q->first_pkt = NULL; - q->nb_packets = 0; - q->size = 0; - almtx_unlock(&q->mutex); -} -static void packet_queue_flush(PacketQueue *q) -{ - almtx_lock(&q->mutex); - q->flushing = true; - almtx_unlock(&q->mutex); - alcnd_signal(&q->cond); -} -static void packet_queue_deinit(PacketQueue *q) -{ - packet_queue_clear(q); - alcnd_destroy(&q->cond); - almtx_destroy(&q->mutex); -} - - -static double get_audio_clock(AudioState *state) -{ - double pts; - - almtx_lock(&state->src_mutex); - /* The audio clock is the timestamp of the sample currently being heard. - * It's based on 4 components: - * 1 - The timestamp of the next sample to buffer (state->current_pts) - * 2 - The length of the source's buffer queue (AL_SEC_LENGTH_SOFT) - * 3 - The offset OpenAL is currently at in the source (the first value - * from AL_SEC_OFFSET_LATENCY_SOFT) - * 4 - The latency between OpenAL and the DAC (the second value from - * AL_SEC_OFFSET_LATENCY_SOFT) - * - * Subtracting the length of the source queue from the next sample's - * timestamp gives the timestamp of the sample at start of the source - * queue. Adding the source offset to that results in the timestamp for - * OpenAL's current position, and subtracting the source latency from that - * gives the timestamp of the sample currently at the DAC. - */ - pts = state->current_pts; - if(state->source) - { - ALdouble offset[2] = { 0.0, 0.0 }; - ALdouble queue_len = 0.0; - ALint status; - - /* NOTE: The source state must be checked last, in case an underrun - * occurs and the source stops between retrieving the offset+latency - * and getting the state. */ - if(has_latency_check) - { - alGetSourcedvSOFT(state->source, AL_SEC_OFFSET_LATENCY_SOFT, offset); - alGetSourcedvSOFT(state->source, AL_SEC_LENGTH_SOFT, &queue_len); - } - else - { - ALint ioffset, ilen; - alGetSourcei(state->source, AL_SAMPLE_OFFSET, &ioffset); - alGetSourcei(state->source, AL_SAMPLE_LENGTH_SOFT, &ilen); - offset[0] = (double)ioffset / state->st->codec->sample_rate; - queue_len = (double)ilen / state->st->codec->sample_rate; - } - alGetSourcei(state->source, AL_SOURCE_STATE, &status); - - /* If the source is AL_STOPPED, then there was an underrun and all - * buffers are processed, so ignore the source queue. The audio thread - * will put the source into an AL_INITIAL state and clear the queue - * when it starts recovery. */ - if(status != AL_STOPPED) - pts = pts - queue_len + offset[0]; - if(status == AL_PLAYING) - pts = pts - offset[1]; - } - almtx_unlock(&state->src_mutex); - - return (pts >= 0.0) ? pts : 0.0; -} -static double get_video_clock(VideoState *state) -{ - double delta = (av_gettime() - state->current_pts_time) / 1000000.0; - return state->current_pts + delta; -} -static double get_external_clock(MovieState *movState) -{ - return (av_gettime()-movState->external_clock_base) / 1000000.0; -} - -double get_master_clock(MovieState *movState) -{ - if(movState->av_sync_type == AV_SYNC_VIDEO_MASTER) - return get_video_clock(&movState->video); - if(movState->av_sync_type == AV_SYNC_AUDIO_MASTER) - return get_audio_clock(&movState->audio); - return get_external_clock(movState); -} - -/* Return how many samples to skip to maintain sync (negative means to - * duplicate samples). */ -static int synchronize_audio(MovieState *movState) -{ - double diff, avg_diff; - double ref_clock; - - if(movState->av_sync_type == AV_SYNC_AUDIO_MASTER) - return 0; - - ref_clock = get_master_clock(movState); - diff = ref_clock - get_audio_clock(&movState->audio); - - if(!(diff < AV_NOSYNC_THRESHOLD)) - { - /* Difference is TOO big; reset diff stuff */ - movState->audio.diff_accum = 0.0; - return 0; - } - - /* Accumulate the diffs */ - movState->audio.diff_accum = movState->audio.diff_accum*movState->audio.diff_avg_coef + diff; - avg_diff = movState->audio.diff_accum*(1.0 - movState->audio.diff_avg_coef); - if(fabs(avg_diff) < movState->audio.diff_threshold) - return 0; - - /* Constrain the per-update difference to avoid exceedingly large skips */ - if(!(diff <= SAMPLE_CORRECTION_MAX_DIFF)) - diff = SAMPLE_CORRECTION_MAX_DIFF; - else if(!(diff >= -SAMPLE_CORRECTION_MAX_DIFF)) - diff = -SAMPLE_CORRECTION_MAX_DIFF; - return (int)(diff*movState->audio.st->codec->sample_rate); -} - -static int audio_decode_frame(MovieState *movState) -{ - AVPacket *pkt = &movState->audio.pkt; - - while(!movState->quit) - { - while(!movState->quit && pkt->size == 0) - { - av_free_packet(pkt); - - /* Get the next packet */ - int err; - if((err=packet_queue_get(&movState->audio.q, pkt, movState)) <= 0) - { - if(err == 0) - break; - return err; - } - if(pkt->data == flush_pkt.data) - { - avcodec_flush_buffers(movState->audio.st->codec); - movState->audio.diff_accum = 0.0; - movState->audio.current_pts = av_q2d(movState->audio.st->time_base)*pkt->pts; - - alSourceRewind(movState->audio.source); - alSourcei(movState->audio.source, AL_BUFFER, 0); - - av_new_packet(pkt, 0); - - return -1; - } - - /* If provided, update w/ pts */ - if(pkt->pts != AV_NOPTS_VALUE) - movState->audio.current_pts = av_q2d(movState->audio.st->time_base)*pkt->pts; - } - - AVFrame *frame = movState->audio.decoded_aframe; - int got_frame = 0; - int len1 = avcodec_decode_audio4(movState->audio.st->codec, frame, - &got_frame, pkt); - if(len1 < 0) break; - - if(len1 <= pkt->size) - { - /* Move the unread data to the front and clear the end bits */ - int remaining = pkt->size - len1; - memmove(pkt->data, &pkt->data[len1], remaining); - av_shrink_packet(pkt, remaining); - } - - if(!got_frame || frame->nb_samples <= 0) - { - av_frame_unref(frame); - continue; - } - - if(frame->nb_samples > movState->audio.samples_max) - { - av_freep(&movState->audio.samples); - av_samples_alloc( - &movState->audio.samples, NULL, movState->audio.st->codec->channels, - frame->nb_samples, movState->audio.dst_sample_fmt, 0 - ); - movState->audio.samples_max = frame->nb_samples; - } - /* Return the amount of sample frames converted */ - int data_size = swr_convert(movState->audio.swres_ctx, - &movState->audio.samples, frame->nb_samples, - (const uint8_t**)frame->data, frame->nb_samples - ); - - av_frame_unref(frame); - return data_size; - } - - return -1; -} - -static int read_audio(MovieState *movState, uint8_t *samples, int length) -{ - int sample_skip = synchronize_audio(movState); - int audio_size = 0; - - /* Read the next chunk of data, refill the buffer, and queue it - * on the source */ - length /= movState->audio.frame_size; - while(audio_size < length) - { - if(movState->audio.samples_len <= 0 || movState->audio.samples_pos >= movState->audio.samples_len) - { - int frame_len = audio_decode_frame(movState); - if(frame_len < 0) return -1; - - movState->audio.samples_len = frame_len; - if(movState->audio.samples_len == 0) - break; - - movState->audio.samples_pos = (movState->audio.samples_len < sample_skip) ? - movState->audio.samples_len : sample_skip; - sample_skip -= movState->audio.samples_pos; - - movState->audio.current_pts += (double)movState->audio.samples_pos / - (double)movState->audio.st->codec->sample_rate; - continue; - } - - int rem = length - audio_size; - if(movState->audio.samples_pos >= 0) - { - int n = movState->audio.frame_size; - int len = movState->audio.samples_len - movState->audio.samples_pos; - if(rem > len) rem = len; - memcpy(samples + audio_size*n, - movState->audio.samples + movState->audio.samples_pos*n, - rem*n); - } - else - { - int n = movState->audio.frame_size; - int len = -movState->audio.samples_pos; - if(rem > len) rem = len; - - /* Add samples by copying the first sample */ - if(n == 1) - { - uint8_t sample = ((uint8_t*)movState->audio.samples)[0]; - uint8_t *q = (uint8_t*)samples + audio_size; - for(int i = 0;i < rem;i++) - *(q++) = sample; - } - else if(n == 2) - { - uint16_t sample = ((uint16_t*)movState->audio.samples)[0]; - uint16_t *q = (uint16_t*)samples + audio_size; - for(int i = 0;i < rem;i++) - *(q++) = sample; - } - else if(n == 4) - { - uint32_t sample = ((uint32_t*)movState->audio.samples)[0]; - uint32_t *q = (uint32_t*)samples + audio_size; - for(int i = 0;i < rem;i++) - *(q++) = sample; - } - else if(n == 8) - { - uint64_t sample = ((uint64_t*)movState->audio.samples)[0]; - uint64_t *q = (uint64_t*)samples + audio_size; - for(int i = 0;i < rem;i++) - *(q++) = sample; - } - else - { - uint8_t *sample = movState->audio.samples; - uint8_t *q = samples + audio_size*n; - for(int i = 0;i < rem;i++) - { - memcpy(q, sample, n); - q += n; - } - } - } - - movState->audio.samples_pos += rem; - movState->audio.current_pts += (double)rem / movState->audio.st->codec->sample_rate; - audio_size += rem; - } - - return audio_size * movState->audio.frame_size; -} - -static int audio_thread(void *userdata) -{ - MovieState *movState = (MovieState*)userdata; - uint8_t *samples = NULL; - ALsizei buffer_len; - - alGenBuffers(AUDIO_BUFFER_QUEUE_SIZE, movState->audio.buffer); - alGenSources(1, &movState->audio.source); - - alSourcei(movState->audio.source, AL_SOURCE_RELATIVE, AL_TRUE); - alSourcei(movState->audio.source, AL_ROLLOFF_FACTOR, 0); - - av_new_packet(&movState->audio.pkt, 0); - - /* Find a suitable format for OpenAL. Currently does not handle surround - * sound (everything non-mono becomes stereo). */ - if(movState->audio.st->codec->sample_fmt == AV_SAMPLE_FMT_U8 || - movState->audio.st->codec->sample_fmt == AV_SAMPLE_FMT_U8P) - { - movState->audio.dst_sample_fmt = AV_SAMPLE_FMT_U8; - movState->audio.frame_size = 1; - if(movState->audio.st->codec->channel_layout == AV_CH_LAYOUT_MONO) - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_MONO; - movState->audio.frame_size *= 1; - movState->audio.format = AL_FORMAT_MONO8; - } - else - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_STEREO; - movState->audio.frame_size *= 2; - movState->audio.format = AL_FORMAT_STEREO8; - } - } - else if((movState->audio.st->codec->sample_fmt == AV_SAMPLE_FMT_FLT || - movState->audio.st->codec->sample_fmt == AV_SAMPLE_FMT_FLTP) && - alIsExtensionPresent("AL_EXT_FLOAT32")) - { - movState->audio.dst_sample_fmt = AV_SAMPLE_FMT_FLT; - movState->audio.frame_size = 4; - if(movState->audio.st->codec->channel_layout == AV_CH_LAYOUT_MONO) - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_MONO; - movState->audio.frame_size *= 1; - movState->audio.format = AL_FORMAT_MONO_FLOAT32; - } - else - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_STEREO; - movState->audio.frame_size *= 2; - movState->audio.format = AL_FORMAT_STEREO_FLOAT32; - } - } - else - { - movState->audio.dst_sample_fmt = AV_SAMPLE_FMT_S16; - movState->audio.frame_size = 2; - if(movState->audio.st->codec->channel_layout == AV_CH_LAYOUT_MONO) - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_MONO; - movState->audio.frame_size *= 1; - movState->audio.format = AL_FORMAT_MONO16; - } - else - { - movState->audio.dst_ch_layout = AV_CH_LAYOUT_STEREO; - movState->audio.frame_size *= 2; - movState->audio.format = AL_FORMAT_STEREO16; - } - } - buffer_len = AUDIO_BUFFER_TIME * movState->audio.st->codec->sample_rate / 1000 * - movState->audio.frame_size; - samples = av_malloc(buffer_len); - - movState->audio.samples = NULL; - movState->audio.samples_max = 0; - movState->audio.samples_pos = 0; - movState->audio.samples_len = 0; - - if(!(movState->audio.decoded_aframe=av_frame_alloc())) - { - fprintf(stderr, "Failed to allocate audio frame\n"); - goto finish; - } - - movState->audio.swres_ctx = swr_alloc_set_opts(NULL, - movState->audio.dst_ch_layout, - movState->audio.dst_sample_fmt, - movState->audio.st->codec->sample_rate, - movState->audio.st->codec->channel_layout, - movState->audio.st->codec->sample_fmt, - movState->audio.st->codec->sample_rate, - 0, NULL - ); - if(!movState->audio.swres_ctx || swr_init(movState->audio.swres_ctx) != 0) - { - fprintf(stderr, "Failed to initialize audio converter\n"); - goto finish; - } - - almtx_lock(&movState->audio.src_mutex); - while(alGetError() == AL_NO_ERROR && !movState->quit) - { - /* First remove any processed buffers. */ - ALint processed; - alGetSourcei(movState->audio.source, AL_BUFFERS_PROCESSED, &processed); - alSourceUnqueueBuffers(movState->audio.source, processed, (ALuint[AUDIO_BUFFER_QUEUE_SIZE]){}); - - /* Refill the buffer queue. */ - ALint queued; - alGetSourcei(movState->audio.source, AL_BUFFERS_QUEUED, &queued); - while(queued < AUDIO_BUFFER_QUEUE_SIZE) - { - int audio_size; - - /* Read the next chunk of data, fill the buffer, and queue it on - * the source */ - audio_size = read_audio(movState, samples, buffer_len); - if(audio_size < 0) break; - - ALuint bufid = movState->audio.buffer[movState->audio.buffer_idx++]; - movState->audio.buffer_idx %= AUDIO_BUFFER_QUEUE_SIZE; - - alBufferData(bufid, movState->audio.format, samples, audio_size, - movState->audio.st->codec->sample_rate); - alSourceQueueBuffers(movState->audio.source, 1, &bufid); - queued++; - } - - /* Check that the source is playing. */ - ALint state; - alGetSourcei(movState->audio.source, AL_SOURCE_STATE, &state); - if(state == AL_STOPPED) - { - /* AL_STOPPED means there was an underrun. Double-check that all - * processed buffers are removed, then rewind the source to get it - * back into an AL_INITIAL state. */ - alGetSourcei(movState->audio.source, AL_BUFFERS_PROCESSED, &processed); - alSourceUnqueueBuffers(movState->audio.source, processed, (ALuint[AUDIO_BUFFER_QUEUE_SIZE]){}); - alSourceRewind(movState->audio.source); - continue; - } - - almtx_unlock(&movState->audio.src_mutex); - - /* (re)start the source if needed, and wait for a buffer to finish */ - if(state != AL_PLAYING && state != AL_PAUSED) - { - alGetSourcei(movState->audio.source, AL_BUFFERS_QUEUED, &queued); - if(queued > 0) alSourcePlay(movState->audio.source); - } - SDL_Delay(AUDIO_BUFFER_TIME); - - almtx_lock(&movState->audio.src_mutex); - } - almtx_unlock(&movState->audio.src_mutex); - -finish: - av_frame_free(&movState->audio.decoded_aframe); - swr_free(&movState->audio.swres_ctx); - - av_freep(&samples); - av_freep(&movState->audio.samples); - - alDeleteSources(1, &movState->audio.source); - alDeleteBuffers(AUDIO_BUFFER_QUEUE_SIZE, movState->audio.buffer); - - return 0; -} - - -static Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque) -{ - (void)interval; - - SDL_PushEvent(&(SDL_Event){ .user={.type=FF_REFRESH_EVENT, .data1=opaque} }); - return 0; /* 0 means stop timer */ -} - -/* Schedule a video refresh in 'delay' ms */ -static void schedule_refresh(MovieState *movState, int delay) -{ - SDL_AddTimer(delay, sdl_refresh_timer_cb, movState); -} - -static void video_display(MovieState *movState, SDL_Window *screen, SDL_Renderer *renderer) -{ - VideoPicture *vp = &movState->video.pictq[movState->video.pictq_rindex]; - - if(!vp->bmp) - return; - - float aspect_ratio; - int win_w, win_h; - int w, h, x, y; - - if(movState->video.st->codec->sample_aspect_ratio.num == 0) - aspect_ratio = 0.0f; - else - { - aspect_ratio = av_q2d(movState->video.st->codec->sample_aspect_ratio) * - movState->video.st->codec->width / - movState->video.st->codec->height; - } - if(aspect_ratio <= 0.0f) - { - aspect_ratio = (float)movState->video.st->codec->width / - (float)movState->video.st->codec->height; - } - - SDL_GetWindowSize(screen, &win_w, &win_h); - h = win_h; - w = ((int)rint(h * aspect_ratio) + 3) & ~3; - if(w > win_w) - { - w = win_w; - h = ((int)rint(w / aspect_ratio) + 3) & ~3; - } - x = (win_w - w) / 2; - y = (win_h - h) / 2; - - SDL_RenderCopy(renderer, vp->bmp, - &(SDL_Rect){ .x=0, .y=0, .w=vp->width, .h=vp->height }, - &(SDL_Rect){ .x=x, .y=y, .w=w, .h=h } - ); - SDL_RenderPresent(renderer); -} - -static void video_refresh_timer(MovieState *movState, SDL_Window *screen, SDL_Renderer *renderer) -{ - if(!movState->video.st) - { - schedule_refresh(movState, 100); - return; - } - - almtx_lock(&movState->video.pictq_mutex); -retry: - if(movState->video.pictq_size == 0) - schedule_refresh(movState, 1); - else - { - VideoPicture *vp = &movState->video.pictq[movState->video.pictq_rindex]; - double actual_delay, delay, sync_threshold, ref_clock, diff; - - movState->video.current_pts = vp->pts; - movState->video.current_pts_time = av_gettime(); - - delay = vp->pts - movState->video.frame_last_pts; /* the pts from last time */ - if(delay <= 0 || delay >= 1.0) - { - /* if incorrect delay, use previous one */ - delay = movState->video.frame_last_delay; - } - /* save for next time */ - movState->video.frame_last_delay = delay; - movState->video.frame_last_pts = vp->pts; - - /* Update delay to sync to clock if not master source. */ - if(movState->av_sync_type != AV_SYNC_VIDEO_MASTER) - { - ref_clock = get_master_clock(movState); - diff = vp->pts - ref_clock; - - /* Skip or repeat the frame. Take delay into account. */ - sync_threshold = (delay > AV_SYNC_THRESHOLD) ? delay : AV_SYNC_THRESHOLD; - if(fabs(diff) < AV_NOSYNC_THRESHOLD) - { - if(diff <= -sync_threshold) - delay = 0; - else if(diff >= sync_threshold) - delay = 2 * delay; - } - } - - movState->video.frame_timer += delay; - /* Compute the REAL delay. */ - actual_delay = movState->video.frame_timer - (av_gettime() / 1000000.0); - if(!(actual_delay >= 0.010)) - { - /* We don't have time to handle this picture, just skip to the next one. */ - movState->video.pictq_rindex = (movState->video.pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE; - movState->video.pictq_size--; - alcnd_signal(&movState->video.pictq_cond); - goto retry; - } - schedule_refresh(movState, (int)(actual_delay*1000.0 + 0.5)); - - /* Show the picture! */ - video_display(movState, screen, renderer); - - /* Update queue for next picture. */ - movState->video.pictq_rindex = (movState->video.pictq_rindex+1)%VIDEO_PICTURE_QUEUE_SIZE; - movState->video.pictq_size--; - alcnd_signal(&movState->video.pictq_cond); - } - almtx_unlock(&movState->video.pictq_mutex); -} - - -static void update_picture(MovieState *movState, bool *first_update, SDL_Window *screen, SDL_Renderer *renderer) -{ - VideoPicture *vp = &movState->video.pictq[movState->video.pictq_windex]; - - /* allocate or resize the buffer! */ - if(!vp->bmp || vp->width != movState->video.st->codec->width || - vp->height != movState->video.st->codec->height) - { - if(vp->bmp) - SDL_DestroyTexture(vp->bmp); - vp->bmp = SDL_CreateTexture( - renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, - movState->video.st->codec->coded_width, movState->video.st->codec->coded_height - ); - if(!vp->bmp) - fprintf(stderr, "Failed to create YV12 texture!\n"); - vp->width = movState->video.st->codec->width; - vp->height = movState->video.st->codec->height; - - if(*first_update && vp->width > 0 && vp->height > 0) - { - /* For the first update, set the window size to the video size. */ - *first_update = false; - - int w = vp->width; - int h = vp->height; - if(movState->video.st->codec->sample_aspect_ratio.num != 0 && - movState->video.st->codec->sample_aspect_ratio.den != 0) - { - double aspect_ratio = av_q2d(movState->video.st->codec->sample_aspect_ratio); - if(aspect_ratio >= 1.0) - w = (int)(w*aspect_ratio + 0.5); - else if(aspect_ratio > 0.0) - h = (int)(h/aspect_ratio + 0.5); - } - SDL_SetWindowSize(screen, w, h); - } - } - - if(vp->bmp) - { - AVFrame *frame = movState->video.decoded_vframe; - void *pixels = NULL; - int pitch = 0; - - if(movState->video.st->codec->pix_fmt == PIX_FMT_YUV420P) - SDL_UpdateYUVTexture(vp->bmp, NULL, - frame->data[0], frame->linesize[0], - frame->data[1], frame->linesize[1], - frame->data[2], frame->linesize[2] - ); - else if(SDL_LockTexture(vp->bmp, NULL, &pixels, &pitch) != 0) - fprintf(stderr, "Failed to lock texture\n"); - else - { - // Convert the image into YUV format that SDL uses - int coded_w = movState->video.st->codec->coded_width; - int coded_h = movState->video.st->codec->coded_height; - int w = movState->video.st->codec->width; - int h = movState->video.st->codec->height; - if(!movState->video.swscale_ctx) - movState->video.swscale_ctx = sws_getContext( - w, h, movState->video.st->codec->pix_fmt, - w, h, PIX_FMT_YUV420P, SWS_X, NULL, NULL, NULL - ); - - /* point pict at the queue */ - AVPicture pict; - pict.data[0] = pixels; - pict.data[2] = pict.data[0] + coded_w*coded_h; - pict.data[1] = pict.data[2] + coded_w*coded_h/4; - - pict.linesize[0] = pitch; - pict.linesize[2] = pitch / 2; - pict.linesize[1] = pitch / 2; - - sws_scale(movState->video.swscale_ctx, (const uint8_t**)frame->data, - frame->linesize, 0, h, pict.data, pict.linesize); - SDL_UnlockTexture(vp->bmp); - } - } - - almtx_lock(&movState->video.pictq_mutex); - vp->updated = true; - almtx_unlock(&movState->video.pictq_mutex); - alcnd_signal(&movState->video.pictq_cond); -} - -static int queue_picture(MovieState *movState, double pts) -{ - /* Wait until we have space for a new pic */ - almtx_lock(&movState->video.pictq_mutex); - while(movState->video.pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !movState->quit) - alcnd_wait(&movState->video.pictq_cond, &movState->video.pictq_mutex); - almtx_unlock(&movState->video.pictq_mutex); - - if(movState->quit) - return -1; - - VideoPicture *vp = &movState->video.pictq[movState->video.pictq_windex]; - - /* We have to create/update the picture in the main thread */ - vp->updated = false; - SDL_PushEvent(&(SDL_Event){ .user={.type=FF_UPDATE_EVENT, .data1=movState} }); - - /* Wait until the picture is updated. */ - almtx_lock(&movState->video.pictq_mutex); - while(!vp->updated && !movState->quit) - alcnd_wait(&movState->video.pictq_cond, &movState->video.pictq_mutex); - almtx_unlock(&movState->video.pictq_mutex); - if(movState->quit) - return -1; - vp->pts = pts; - - movState->video.pictq_windex = (movState->video.pictq_windex+1)%VIDEO_PICTURE_QUEUE_SIZE; - almtx_lock(&movState->video.pictq_mutex); - movState->video.pictq_size++; - almtx_unlock(&movState->video.pictq_mutex); - - return 0; -} - -static double synchronize_video(MovieState *movState, double pts) -{ - double frame_delay; - - if(pts == 0.0) /* if we aren't given a pts, set it to the clock */ - pts = movState->video.clock; - else /* if we have pts, set video clock to it */ - movState->video.clock = pts; - - /* update the video clock */ - frame_delay = av_q2d(movState->video.st->codec->time_base); - /* if we are repeating a frame, adjust clock accordingly */ - frame_delay += movState->video.decoded_vframe->repeat_pict * (frame_delay * 0.5); - movState->video.clock += frame_delay; - return pts; -} - -int video_thread(void *arg) -{ - MovieState *movState = (MovieState*)arg; - AVPacket *packet = (AVPacket[1]){}; - int64_t saved_pts, pkt_pts; - int frameFinished; - - movState->video.decoded_vframe = av_frame_alloc(); - while(packet_queue_get(&movState->video.q, packet, movState) >= 0) - { - if(packet->data == flush_pkt.data) - { - avcodec_flush_buffers(movState->video.st->codec); - - almtx_lock(&movState->video.pictq_mutex); - movState->video.pictq_size = 0; - movState->video.pictq_rindex = 0; - movState->video.pictq_windex = 0; - almtx_unlock(&movState->video.pictq_mutex); - - movState->video.clock = av_q2d(movState->video.st->time_base)*packet->pts; - movState->video.current_pts = movState->video.clock; - movState->video.current_pts_time = av_gettime(); - continue; - } - - pkt_pts = packet->pts; - - /* Decode video frame */ - avcodec_decode_video2(movState->video.st->codec, movState->video.decoded_vframe, - &frameFinished, packet); - if(pkt_pts != AV_NOPTS_VALUE && !movState->video.decoded_vframe->opaque) - { - /* Store the packet's original pts in the frame, in case the frame - * is not finished decoding yet. */ - saved_pts = pkt_pts; - movState->video.decoded_vframe->opaque = &saved_pts; - } - - av_free_packet(packet); - - if(frameFinished) - { - double pts = av_q2d(movState->video.st->time_base); - if(packet->dts != AV_NOPTS_VALUE) - pts *= packet->dts; - else if(movState->video.decoded_vframe->opaque) - pts *= *(int64_t*)movState->video.decoded_vframe->opaque; - else - pts *= 0.0; - movState->video.decoded_vframe->opaque = NULL; - - pts = synchronize_video(movState, pts); - if(queue_picture(movState, pts) < 0) - break; - } - } - - sws_freeContext(movState->video.swscale_ctx); - movState->video.swscale_ctx = NULL; - av_frame_free(&movState->video.decoded_vframe); - return 0; -} - - -static int stream_component_open(MovieState *movState, int stream_index) -{ - AVFormatContext *pFormatCtx = movState->pFormatCtx; - AVCodecContext *codecCtx; - AVCodec *codec; - - if(stream_index < 0 || (unsigned int)stream_index >= pFormatCtx->nb_streams) - return -1; - - /* Get a pointer to the codec context for the video stream, and open the - * associated codec */ - codecCtx = pFormatCtx->streams[stream_index]->codec; - - codec = avcodec_find_decoder(codecCtx->codec_id); - if(!codec || avcodec_open2(codecCtx, codec, NULL) < 0) - { - fprintf(stderr, "Unsupported codec!\n"); - return -1; - } - - /* Initialize and start the media type handler */ - switch(codecCtx->codec_type) - { - case AVMEDIA_TYPE_AUDIO: - movState->audioStream = stream_index; - movState->audio.st = pFormatCtx->streams[stream_index]; - - /* Averaging filter for audio sync */ - movState->audio.diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB); - /* Correct audio only if larger error than this */ - movState->audio.diff_threshold = 2.0 * 0.050/* 50 ms */; - - memset(&movState->audio.pkt, 0, sizeof(movState->audio.pkt)); - if(althrd_create(&movState->audio.thread, audio_thread, movState) != althrd_success) - { - movState->audioStream = -1; - movState->audio.st = NULL; - } - break; - - case AVMEDIA_TYPE_VIDEO: - movState->videoStream = stream_index; - movState->video.st = pFormatCtx->streams[stream_index]; - - movState->video.current_pts_time = av_gettime(); - movState->video.frame_timer = (double)movState->video.current_pts_time / - 1000000.0; - movState->video.frame_last_delay = 40e-3; - - if(althrd_create(&movState->video.thread, video_thread, movState) != althrd_success) - { - movState->videoStream = -1; - movState->video.st = NULL; - } - break; - - default: - break; - } - - return 0; -} - -static int decode_interrupt_cb(void *ctx) -{ - return ((MovieState*)ctx)->quit; -} - -int decode_thread(void *arg) -{ - MovieState *movState = (MovieState *)arg; - AVFormatContext *fmtCtx = movState->pFormatCtx; - AVPacket *packet = (AVPacket[1]){}; - int video_index = -1; - int audio_index = -1; - - movState->videoStream = -1; - movState->audioStream = -1; - - /* Dump information about file onto standard error */ - av_dump_format(fmtCtx, 0, movState->filename, 0); - - /* Find the first video and audio streams */ - for(unsigned int i = 0;i < fmtCtx->nb_streams;i++) - { - if(fmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_index < 0) - video_index = i; - else if(fmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_index < 0) - audio_index = i; - } - movState->external_clock_base = av_gettime(); - if(audio_index >= 0) - stream_component_open(movState, audio_index); - if(video_index >= 0) - stream_component_open(movState, video_index); - - if(movState->videoStream < 0 && movState->audioStream < 0) - { - fprintf(stderr, "%s: could not open codecs\n", movState->filename); - goto fail; - } - - /* Main packet handling loop */ - while(!movState->quit) - { - if(movState->seek_req) - { - int64_t seek_target = movState->seek_pos; - int stream_index= -1; - - /* Prefer seeking on the video stream. */ - if(movState->videoStream >= 0) - stream_index = movState->videoStream; - else if(movState->audioStream >= 0) - stream_index = movState->audioStream; - - /* Get a seek timestamp for the appropriate stream. */ - int64_t timestamp = seek_target; - if(stream_index >= 0) - timestamp = av_rescale_q(seek_target, AV_TIME_BASE_Q, fmtCtx->streams[stream_index]->time_base); - - if(av_seek_frame(movState->pFormatCtx, stream_index, timestamp, 0) < 0) - fprintf(stderr, "%s: error while seeking\n", movState->pFormatCtx->filename); - else - { - /* Seek successful, clear the packet queues and send a special - * 'flush' packet with the new stream clock time. */ - if(movState->audioStream >= 0) - { - packet_queue_clear(&movState->audio.q); - flush_pkt.pts = av_rescale_q(seek_target, AV_TIME_BASE_Q, - fmtCtx->streams[movState->audioStream]->time_base - ); - packet_queue_put(&movState->audio.q, &flush_pkt); - } - if(movState->videoStream >= 0) - { - packet_queue_clear(&movState->video.q); - flush_pkt.pts = av_rescale_q(seek_target, AV_TIME_BASE_Q, - fmtCtx->streams[movState->videoStream]->time_base - ); - packet_queue_put(&movState->video.q, &flush_pkt); - } - movState->external_clock_base = av_gettime() - seek_target; - } - movState->seek_req = false; - } - - if(movState->audio.q.size >= MAX_AUDIOQ_SIZE || - movState->video.q.size >= MAX_VIDEOQ_SIZE) - { - SDL_Delay(10); - continue; - } - - if(av_read_frame(movState->pFormatCtx, packet) < 0) - { - packet_queue_flush(&movState->video.q); - packet_queue_flush(&movState->audio.q); - break; - } - - /* Place the packet in the queue it's meant for, or discard it. */ - if(packet->stream_index == movState->videoStream) - packet_queue_put(&movState->video.q, packet); - else if(packet->stream_index == movState->audioStream) - packet_queue_put(&movState->audio.q, packet); - else - av_free_packet(packet); - } - - /* all done - wait for it */ - while(!movState->quit) - { - if(movState->audio.q.nb_packets == 0 && movState->video.q.nb_packets == 0) - break; - SDL_Delay(100); - } - -fail: - movState->quit = true; - packet_queue_flush(&movState->video.q); - packet_queue_flush(&movState->audio.q); - - if(movState->videoStream >= 0) - althrd_join(movState->video.thread, NULL); - if(movState->audioStream >= 0) - althrd_join(movState->audio.thread, NULL); - - SDL_PushEvent(&(SDL_Event){ .user={.type=FF_QUIT_EVENT, .data1=movState} }); - - return 0; -} - - -static void stream_seek(MovieState *movState, double incr) -{ - if(!movState->seek_req) - { - double newtime = get_master_clock(movState)+incr; - if(newtime <= 0.0) movState->seek_pos = 0; - else movState->seek_pos = (int64_t)(newtime * AV_TIME_BASE); - movState->seek_req = true; - } -} - -int main(int argc, char *argv[]) -{ - SDL_Event event; - MovieState *movState; - bool first_update = true; - SDL_Window *screen; - SDL_Renderer *renderer; - ALCdevice *device; - ALCcontext *context; - - if(argc < 2) - { - fprintf(stderr, "Usage: %s \n", argv[0]); - return 1; - } - /* Register all formats and codecs */ - av_register_all(); - /* Initialize networking protocols */ - avformat_network_init(); - - if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) - { - fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); - return 1; - } - - /* Make a window to put our video */ - screen = SDL_CreateWindow("alffplay", 0, 0, 640, 480, SDL_WINDOW_RESIZABLE); - if(!screen) - { - fprintf(stderr, "SDL: could not set video mode - exiting\n"); - return 1; - } - /* Make a renderer to handle the texture image surface and rendering. */ - renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED); - if(renderer) - { - SDL_RendererInfo rinf; - bool ok = false; - - /* Make sure the renderer supports YV12 textures. If not, fallback to a - * software renderer. */ - if(SDL_GetRendererInfo(renderer, &rinf) == 0) - { - for(Uint32 i = 0;!ok && i < rinf.num_texture_formats;i++) - ok = (rinf.texture_formats[i] == SDL_PIXELFORMAT_YV12); - } - if(!ok) - { - fprintf(stderr, "YV12 pixelformat textures not supported on renderer %s\n", rinf.name); - SDL_DestroyRenderer(renderer); - renderer = NULL; - } - } - if(!renderer) - renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE); - if(!renderer) - { - fprintf(stderr, "SDL: could not create renderer - exiting\n"); - return 1; - } - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderFillRect(renderer, NULL); - SDL_RenderPresent(renderer); - - /* Open an audio device */ - device = alcOpenDevice(NULL); - if(!device) - { - fprintf(stderr, "OpenAL: could not open device - exiting\n"); - return 1; - } - context = alcCreateContext(device, NULL); - if(!context) - { - fprintf(stderr, "OpenAL: could not create context - exiting\n"); - return 1; - } - if(alcMakeContextCurrent(context) == ALC_FALSE) - { - fprintf(stderr, "OpenAL: could not make context current - exiting\n"); - return 1; - } - - if(!alIsExtensionPresent("AL_SOFT_source_length")) - { - fprintf(stderr, "Required AL_SOFT_source_length not supported - exiting\n"); - return 1; - } - - if(!alIsExtensionPresent("AL_SOFT_source_latency")) - fprintf(stderr, "AL_SOFT_source_latency not supported, audio may be a bit laggy.\n"); - else - { - alGetSourcedvSOFT = alGetProcAddress("alGetSourcedvSOFT"); - has_latency_check = true; - } - - - movState = av_mallocz(sizeof(MovieState)); - - av_strlcpy(movState->filename, argv[1], sizeof(movState->filename)); - - packet_queue_init(&movState->audio.q); - packet_queue_init(&movState->video.q); - - almtx_init(&movState->video.pictq_mutex, almtx_plain); - alcnd_init(&movState->video.pictq_cond); - almtx_init(&movState->audio.src_mutex, almtx_recursive); - - movState->av_sync_type = DEFAULT_AV_SYNC_TYPE; - - movState->pFormatCtx = avformat_alloc_context(); - movState->pFormatCtx->interrupt_callback = (AVIOInterruptCB){.callback=decode_interrupt_cb, .opaque=movState}; - - if(avio_open2(&movState->pFormatCtx->pb, movState->filename, AVIO_FLAG_READ, - &movState->pFormatCtx->interrupt_callback, NULL)) - { - fprintf(stderr, "Failed to open %s\n", movState->filename); - return 1; - } - - /* Open movie file */ - if(avformat_open_input(&movState->pFormatCtx, movState->filename, NULL, NULL) != 0) - { - fprintf(stderr, "Failed to open %s\n", movState->filename); - return 1; - } - - /* Retrieve stream information */ - if(avformat_find_stream_info(movState->pFormatCtx, NULL) < 0) - { - fprintf(stderr, "%s: failed to find stream info\n", movState->filename); - return 1; - } - - schedule_refresh(movState, 40); - - - if(althrd_create(&movState->parse_thread, decode_thread, movState) != althrd_success) - { - fprintf(stderr, "Failed to create parse thread!\n"); - return 1; - } - while(SDL_WaitEvent(&event) == 1) - { - switch(event.type) - { - case SDL_KEYDOWN: - switch(event.key.keysym.sym) - { - case SDLK_ESCAPE: - movState->quit = true; - break; - - case SDLK_LEFT: - stream_seek(movState, -10.0); - break; - case SDLK_RIGHT: - stream_seek(movState, 10.0); - break; - case SDLK_UP: - stream_seek(movState, 30.0); - break; - case SDLK_DOWN: - stream_seek(movState, -30.0); - break; - - default: - break; - } - break; - - case SDL_WINDOWEVENT: - switch(event.window.event) - { - case SDL_WINDOWEVENT_RESIZED: - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderFillRect(renderer, NULL); - break; - - default: - break; - } - break; - - case SDL_QUIT: - movState->quit = true; - break; - - case FF_UPDATE_EVENT: - update_picture(event.user.data1, &first_update, screen, renderer); - break; - - case FF_REFRESH_EVENT: - video_refresh_timer(event.user.data1, screen, renderer); - break; - - case FF_QUIT_EVENT: - althrd_join(movState->parse_thread, NULL); - - avformat_close_input(&movState->pFormatCtx); - - almtx_destroy(&movState->audio.src_mutex); - almtx_destroy(&movState->video.pictq_mutex); - alcnd_destroy(&movState->video.pictq_cond); - packet_queue_deinit(&movState->video.q); - packet_queue_deinit(&movState->audio.q); - - alcMakeContextCurrent(NULL); - alcDestroyContext(context); - alcCloseDevice(device); - - SDL_Quit(); - exit(0); - - default: - break; - } - } - - fprintf(stderr, "SDL_WaitEvent error - %s\n", SDL_GetError()); - return 1; -} diff --git a/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.c b/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.c deleted file mode 100644 index 4582321c..00000000 --- a/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - * OpenAL Helpers - * - * Copyright (c) 2011 by Chris Robinson - * - * 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 routines to help with some menial OpenAL-related tasks, - * such as opening a device and setting up a context, closing the device and - * destroying its context, converting between frame counts and byte lengths, - * finding an appropriate buffer format, and getting readable strings for - * channel configs and sample types. */ - -#include - -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" - -#include "alhelpers.h" - - -/* InitAL opens the default device and sets up a context using default - * attributes, making the program ready to call OpenAL functions. */ -int InitAL(void) -{ - ALCdevice *device; - ALCcontext *ctx; - - /* Open and initialize a device with default settings */ - device = alcOpenDevice(NULL); - if(!device) - { - fprintf(stderr, "Could not open a device!\n"); - return 1; - } - - 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; -} - -/* CloseAL closes the device belonging to the current context, and destroys the - * context. */ -void CloseAL(void) -{ - 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; - - /* If using AL_SOFT_buffer_samples, try looking through its formats */ - if(palIsBufferFormatSupportedSOFT) - { - /* AL_SOFT_buffer_samples is more lenient with matching formats. The - * specified sample type does not need to match the returned format, - * but it is nice to try to get something close. */ - if(type == AL_UNSIGNED_BYTE_SOFT || type == AL_BYTE_SOFT) - { - if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT; - } - else if(type == AL_UNSIGNED_SHORT_SOFT || type == AL_SHORT_SOFT) - { - if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT; - } - else if(type == AL_UNSIGNED_BYTE3_SOFT || type == AL_BYTE3_SOFT || - type == AL_UNSIGNED_INT_SOFT || type == AL_INT_SOFT || - type == AL_FLOAT_SOFT || type == AL_DOUBLE_SOFT) - { - if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT; - } - - if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) - format = AL_NONE; - - /* A matching format was not found or supported. Try 32-bit float. */ - if(format == AL_NONE) - { - if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT; - - if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) - format = AL_NONE; - } - /* 32-bit float not supported. Try 16-bit int. */ - if(format == AL_NONE) - { - if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT; - - if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) - format = AL_NONE; - } - /* 16-bit int not supported. Try 8-bit int. */ - if(format == AL_NONE) - { - if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT; - else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT; - else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT; - else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT; - else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT; - else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT; - - if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format)) - format = AL_NONE; - } - - return format; - } - - /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1, - * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and - * AL_EXT_DOUBLE for 64-bit float samples. */ - if(type == AL_UNSIGNED_BYTE_SOFT) - { - if(channels == AL_MONO_SOFT) - format = AL_FORMAT_MONO8; - else if(channels == AL_STEREO_SOFT) - format = AL_FORMAT_STEREO8; - else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) - { - if(channels == AL_QUAD_SOFT) - format = alGetEnumValue("AL_FORMAT_QUAD8"); - else if(channels == AL_5POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_51CHN8"); - else if(channels == AL_6POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_61CHN8"); - else if(channels == AL_7POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_71CHN8"); - } - } - else if(type == AL_SHORT_SOFT) - { - if(channels == AL_MONO_SOFT) - format = AL_FORMAT_MONO16; - else if(channels == AL_STEREO_SOFT) - format = AL_FORMAT_STEREO16; - else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) - { - if(channels == AL_QUAD_SOFT) - format = alGetEnumValue("AL_FORMAT_QUAD16"); - else if(channels == AL_5POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_51CHN16"); - else if(channels == AL_6POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_61CHN16"); - else if(channels == AL_7POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_71CHN16"); - } - } - else if(type == AL_FLOAT_SOFT && alIsExtensionPresent("AL_EXT_FLOAT32")) - { - if(channels == AL_MONO_SOFT) - format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32"); - else if(channels == AL_STEREO_SOFT) - format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32"); - else if(alIsExtensionPresent("AL_EXT_MCFORMATS")) - { - if(channels == AL_QUAD_SOFT) - format = alGetEnumValue("AL_FORMAT_QUAD32"); - else if(channels == AL_5POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_51CHN32"); - else if(channels == AL_6POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_61CHN32"); - else if(channels == AL_7POINT1_SOFT) - format = alGetEnumValue("AL_FORMAT_71CHN32"); - } - } - else if(type == AL_DOUBLE_SOFT && alIsExtensionPresent("AL_EXT_DOUBLE")) - { - if(channels == AL_MONO_SOFT) - format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE"); - else if(channels == AL_STEREO_SOFT) - format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE"); - } - - /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as - * opposed to 0. Correct it. */ - if(format == -1) - format = 0; - - return format; -} - - -void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate, - ALenum internalformat, ALsizei samples, - ALenum channels, ALenum type, - const ALvoid *data) -{ - alBufferData(buffer, internalformat, data, - FramesToBytes(samples, channels, type), - samplerate); -} - - -const char *ChannelsName(ALenum chans) -{ - switch(chans) - { - 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"; - } - return "Unknown Channels"; -} - -const char *TypeName(ALenum type) -{ - 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); -} diff --git a/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.h b/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.h deleted file mode 100644 index 62ed5be2..00000000 --- a/love/src/jni/openal-soft-1.17.0/examples/common/alhelpers.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef ALHELPERS_H -#define ALHELPERS_H - -#ifndef _WIN32 -#include -#define Sleep(x) usleep((x)*1000) -#else -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include "AL/alc.h" -#include "AL/al.h" -#include "AL/alext.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Some helper functions to get the name from the channel and type enums. */ -const char *ChannelsName(ALenum chans); -const char *TypeName(ALenum type); - -/* Helpers to convert frame counts and byte lengths. */ -ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type); -ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type); - -/* Retrieves a compatible buffer format given the channel configuration and - * sample type. If an alIsBufferFormatSupportedSOFT-compatible function is - * provided, it will be called to find the closest-matching format from - * AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be - * found. */ -ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT); - -/* Loads samples into a buffer using the standard alBufferData call, but with a - * LPALBUFFERSAMPLESSOFT-compatible prototype. Assumes internalformat is valid - * for alBufferData, and that channels and type match it. */ -void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate, - ALenum internalformat, ALsizei samples, - ALenum channels, ALenum type, - const ALvoid *data); - -/* Easy device init/deinit functions. InitAL returns 0 on success. */ -int InitAL(void); -void CloseAL(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* ALHELPERS_H */ diff --git a/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.c b/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.c deleted file mode 100644 index 79a5bf32..00000000 --- a/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * SDL_sound Decoder Helpers - * - * Copyright (c) 2013 by Chris Robinson - * - * 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 routines for helping to decode audio using SDL_sound. - * There's very little OpenAL-specific code here. - */ -#include "sdl_sound.h" - -#include -#include -#include -#include -#include - -#include - -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" - -#include "alhelpers.h" - - -static int done_init = 0; - -FilePtr openAudioFile(const char *fname, size_t buftime_ms) -{ - FilePtr file; - ALuint rate; - Uint32 bufsize; - ALenum chans, type; - - /* We need to make sure SDL_sound is initialized. */ - if(!done_init) - { - Sound_Init(); - done_init = 1; - } - - file = Sound_NewSampleFromFile(fname, NULL, 0); - if(!file) - { - fprintf(stderr, "Failed to open %s: %s\n", fname, Sound_GetError()); - return NULL; - } - - if(getAudioInfo(file, &rate, &chans, &type) != 0) - { - Sound_FreeSample(file); - return NULL; - } - - bufsize = FramesToBytes((ALsizei)(buftime_ms/1000.0*rate), chans, type); - if(Sound_SetBufferSize(file, bufsize) == 0) - { - fprintf(stderr, "Failed to set buffer size to %u bytes: %s\n", bufsize, Sound_GetError()); - Sound_FreeSample(file); - return NULL; - } - - return file; -} - -void closeAudioFile(FilePtr file) -{ - if(file) - Sound_FreeSample(file); -} - - -int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type) -{ - if(file->actual.channels == 1) - *channels = AL_MONO_SOFT; - else if(file->actual.channels == 2) - *channels = AL_STEREO_SOFT; - else - { - fprintf(stderr, "Unsupported channel count: %d\n", file->actual.channels); - return 1; - } - - if(file->actual.format == AUDIO_U8) - *type = AL_UNSIGNED_BYTE_SOFT; - else if(file->actual.format == AUDIO_S8) - *type = AL_BYTE_SOFT; - else if(file->actual.format == AUDIO_U16LSB || file->actual.format == AUDIO_U16MSB) - *type = AL_UNSIGNED_SHORT_SOFT; - else if(file->actual.format == AUDIO_S16LSB || file->actual.format == AUDIO_S16MSB) - *type = AL_SHORT_SOFT; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", file->actual.format); - return 1; - } - - *rate = file->actual.rate; - - return 0; -} - - -uint8_t *getAudioData(FilePtr file, size_t *length) -{ - *length = Sound_Decode(file); - if(*length == 0) - return NULL; - if((file->actual.format == AUDIO_U16LSB && AUDIO_U16LSB != AUDIO_U16SYS) || - (file->actual.format == AUDIO_U16MSB && AUDIO_U16MSB != AUDIO_U16SYS) || - (file->actual.format == AUDIO_S16LSB && AUDIO_S16LSB != AUDIO_S16SYS) || - (file->actual.format == AUDIO_S16MSB && AUDIO_S16MSB != AUDIO_S16SYS)) - { - /* Swap bytes if the decoded endianness doesn't match the system. */ - char *buffer = file->buffer; - size_t i; - for(i = 0;i < *length;i+=2) - { - char b = buffer[i]; - buffer[i] = buffer[i+1]; - buffer[i+1] = b; - } - } - return file->buffer; -} - -void *decodeAudioStream(FilePtr file, size_t *length) -{ - Uint32 got; - char *mem; - - got = Sound_DecodeAll(file); - if(got == 0) - { - *length = 0; - return NULL; - } - - mem = malloc(got); - memcpy(mem, file->buffer, got); - - *length = got; - return mem; -} diff --git a/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.h b/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.h deleted file mode 100644 index e93ab92b..00000000 --- a/love/src/jni/openal-soft-1.17.0/examples/common/sdl_sound.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef EXAMPLES_SDL_SOUND_H -#define EXAMPLES_SDL_SOUND_H - -#include "AL/al.h" - -#include - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Opaque handles to files and streams. Apps don't need to concern themselves - * with the internals */ -typedef Sound_Sample *FilePtr; - -/* Opens a file with SDL_sound, and specifies the size of the sample buffer in - * milliseconds. */ -FilePtr openAudioFile(const char *fname, size_t buftime_ms); - -/* Closes/frees an opened file */ -void closeAudioFile(FilePtr file); - -/* Returns information about the given audio stream. Returns 0 on success. */ -int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type); - -/* Returns a pointer to the next available chunk of decoded audio. 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 getAudioData. */ -uint8_t *getAudioData(FilePtr file, size_t *length); - -/* Decodes all remaining data from the stream and returns a buffer containing - * the audio data, with the size stored in 'length'. The returned pointer must - * be freed with a call to free(). Note that since this decodes the whole - * stream, using it on lengthy streams (eg, music) will use a lot of memory. - * Such streams are better handled using getAudioData to keep smaller chunks in - * memory at any given time. */ -void *decodeAudioStream(FilePtr, size_t *length); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* EXAMPLES_SDL_SOUND_H */ diff --git a/love/src/jni/openal-soft-1.17.0/hrtf/default-44100.mhr b/love/src/jni/openal-soft-1.17.0/hrtf/default-44100.mhr deleted file mode 100644 index e0d0bf4b..00000000 Binary files a/love/src/jni/openal-soft-1.17.0/hrtf/default-44100.mhr and /dev/null differ diff --git a/love/src/jni/openal-soft-1.17.0/hrtf/default-48000.mhr b/love/src/jni/openal-soft-1.17.0/hrtf/default-48000.mhr deleted file mode 100644 index 0ad547ad..00000000 Binary files a/love/src/jni/openal-soft-1.17.0/hrtf/default-48000.mhr and /dev/null differ diff --git a/love/src/jni/openal-soft-1.17.0/include/atomic.h b/love/src/jni/openal-soft-1.17.0/include/atomic.h deleted file mode 100644 index d761890e..00000000 --- a/love/src/jni/openal-soft-1.17.0/include/atomic.h +++ /dev/null @@ -1,313 +0,0 @@ -#ifndef AL_ATOMIC_H -#define AL_ATOMIC_H - -#include "static_assert.h" -#include "bool.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *volatile XchgPtr; - -/* Atomics using C11 */ -#ifdef HAVE_C11_ATOMIC - -#include - -inline int ExchangeInt(volatile int *ptr, int newval) -{ return atomic_exchange(ptr, newval); } -inline void *ExchangePtr(XchgPtr *ptr, void *newval) -{ return atomic_exchange(ptr, newval); } - - -#define ATOMIC(T) struct { T _Atomic value; } - -#define ATOMIC_INIT(_val, _newval) atomic_init(&(_val)->value, (_newval)) -#define ATOMIC_INIT_STATIC(_newval) {ATOMIC_VAR_INIT(_newval)} - -#define ATOMIC_LOAD(_val) atomic_load(&(_val)->value) -#define ATOMIC_STORE(_val, _newval) atomic_store(&(_val)->value, (_newval)) - -#define ATOMIC_ADD(T, _val, _incr) atomic_fetch_add(&(_val)->value, (_incr)) -#define ATOMIC_SUB(T, _val, _decr) atomic_fetch_sub(&(_val)->value, (_decr)) - -#define ATOMIC_EXCHANGE(T, _val, _newval) atomic_exchange(&(_val)->value, (_newval)) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) \ - atomic_compare_exchange_strong(&(_val)->value, (_oldval), (_newval)) -#define ATOMIC_COMPARE_EXCHANGE_WEAK(T, _val, _oldval, _newval) \ - atomic_compare_exchange_weak(&(_val)->value, (_oldval), (_newval)) - -/* Atomics using GCC intrinsics */ -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) && !defined(__QNXNTO__) - -inline int ExchangeInt(volatile int *ptr, int newval) -{ return __sync_lock_test_and_set(ptr, newval); } -inline void *ExchangePtr(XchgPtr *ptr, void *newval) -{ return __sync_lock_test_and_set(ptr, newval); } - - -#define ATOMIC(T) struct { T volatile value; } - -#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) -#define ATOMIC_INIT_STATIC(_newval) {(_newval)} - -#define ATOMIC_LOAD(_val) __extension__({ \ - __typeof((_val)->value) _r = (_val)->value; \ - __asm__ __volatile__("" ::: "memory"); \ - _r; \ -}) -#define ATOMIC_STORE(_val, _newval) do { \ - __asm__ __volatile__("" ::: "memory"); \ - (_val)->value = (_newval); \ -} while(0) - -#define ATOMIC_ADD(T, _val, _incr) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - __sync_fetch_and_add(&(_val)->value, (_incr)); \ -}) -#define ATOMIC_SUB(T, _val, _decr) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - __sync_fetch_and_sub(&(_val)->value, (_decr)); \ -}) - -#define ATOMIC_EXCHANGE(T, _val, _newval) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - __sync_lock_test_and_set(&(_val)->value, (_newval)); \ -}) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) __extension__({ \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _o = *(_oldval); \ - *(_oldval) = __sync_val_compare_and_swap(&(_val)->value, _o, (_newval)); \ - *(_oldval) == _o; \ -}) - -/* Atomics using x86/x86-64 GCC inline assembly */ -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - -#define WRAP_ADD(ret, dest, incr) __asm__ __volatile__( \ - "lock; xaddl %0,(%1)" \ - : "=r" (ret) \ - : "r" (dest), "0" (incr) \ - : "memory" \ -) -#define WRAP_SUB(ret, dest, decr) __asm__ __volatile__( \ - "lock; xaddl %0,(%1)" \ - : "=r" (ret) \ - : "r" (dest), "0" (-(decr)) \ - : "memory" \ -) - -#define WRAP_XCHG(S, ret, dest, newval) __asm__ __volatile__( \ - "lock; xchg"S" %0,(%1)" \ - : "=r" (ret) \ - : "r" (dest), "0" (newval) \ - : "memory" \ -) -#define WRAP_CMPXCHG(S, ret, dest, oldval, newval) __asm__ __volatile__( \ - "lock; cmpxchg"S" %2,(%1)" \ - : "=a" (ret) \ - : "r" (dest), "r" (newval), "0" (oldval) \ - : "memory" \ -) - - -inline int ExchangeInt(volatile int *dest, int newval) -{ int ret; WRAP_XCHG("l", ret, dest, newval); return ret; } - -#ifdef __i386__ -inline void *ExchangePtr(XchgPtr *dest, void *newval) -{ void *ret; WRAP_XCHG("l", ret, dest, newval); return ret; } -#else -inline void *ExchangePtr(XchgPtr *dest, void *newval) -{ void *ret; WRAP_XCHG("q", ret, dest, newval); return ret; } -#endif - - -#define ATOMIC(T) struct { T volatile value; } - -#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) -#define ATOMIC_INIT_STATIC(_newval) {(_newval)} - -#define ATOMIC_LOAD(_val) __extension__({ \ - __typeof((_val)->value) _r = (_val)->value; \ - __asm__ __volatile__("" ::: "memory"); \ - _r; \ -}) -#define ATOMIC_STORE(_val, _newval) do { \ - __asm__ __volatile__("" ::: "memory"); \ - (_val)->value = (_newval); \ -} while(0) - -#define ATOMIC_ADD(T, _val, _incr) __extension__({ \ - static_assert(sizeof(T)==4, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _r; \ - WRAP_ADD(_r, &(_val)->value, (T)(_incr)); \ - _r; \ -}) -#define ATOMIC_SUB(T, _val, _decr) __extension__({ \ - static_assert(sizeof(T)==4, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _r; \ - WRAP_SUB(_r, &(_val)->value, (T)(_decr)); \ - _r; \ -}) - -#define ATOMIC_EXCHANGE(T, _val, _newval) __extension__({ \ - static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _r; \ - if(sizeof(T) == 4) WRAP_XCHG("l", _r, &(_val)->value, (T)(_newval)); \ - else if(sizeof(T) == 8) WRAP_XCHG("q", _r, &(_val)->value, (T)(_newval)); \ - _r; \ -}) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) __extension__({ \ - static_assert(sizeof(T)==4 || sizeof(T)==8, "Type "#T" has incorrect size!"); \ - static_assert(sizeof(T)==sizeof((_val)->value), "Type "#T" has incorrect size!"); \ - T _old = *(_oldval); \ - if(sizeof(T) == 4) WRAP_CMPXCHG("l", *(_oldval), &(_val)->value, _old, (T)(_newval)); \ - else if(sizeof(T) == 8) WRAP_CMPXCHG("q", *(_oldval), &(_val)->value, _old, (T)(_newval)); \ - *(_oldval) == _old; \ -}) - -/* Atomics using Windows methods */ -#elif defined(_WIN32) - -#define WIN32_LEAN_AND_MEAN -#include - -/* NOTE: This mess is *extremely* noisy, at least on GCC. It works by wrapping - * Windows' 32-bit and 64-bit atomic methods, which are then casted to use the - * given type based on its size (e.g. int and float use 32-bit atomics). This - * is fine for the swap and compare-and-swap methods, although the add and - * subtract methods only work properly for integer types. - * - * Despite how noisy it is, it's unfortunately the only way that doesn't rely - * on C99 (damn MSVC). - */ - -inline LONG AtomicAdd32(volatile LONG *dest, LONG incr) -{ - return InterlockedExchangeAdd(dest, incr); -} -inline LONG AtomicSub32(volatile LONG *dest, LONG decr) -{ - return InterlockedExchangeAdd(dest, -decr); -} - -inline LONG AtomicSwap32(volatile LONG *dest, LONG newval) -{ - return InterlockedExchange(dest, newval); -} -inline LONGLONG AtomicSwap64(volatile LONGLONG *dest, LONGLONG newval) -{ - return InterlockedExchange64(dest, newval); -} - -inline bool CompareAndSwap32(volatile LONG *dest, LONG newval, LONG *oldval) -{ - LONG old = *oldval; - *oldval = InterlockedCompareExchange(dest, newval, *oldval); - return old == *oldval; -} -inline bool CompareAndSwap64(volatile LONGLONG *dest, LONGLONG newval, LONGLONG *oldval) -{ - LONGLONG old = *oldval; - *oldval = InterlockedCompareExchange64(dest, newval, *oldval); - return old == *oldval; -} - -#define WRAP_ADDSUB(T, _func, _ptr, _amnt) ((T(*)(T volatile*,T))_func)((_ptr), (_amnt)) -#define WRAP_XCHG(T, _func, _ptr, _newval) ((T(*)(T volatile*,T))_func)((_ptr), (_newval)) -#define WRAP_CMPXCHG(T, _func, _ptr, _newval, _oldval) ((bool(*)(T volatile*,T,T*))_func)((_ptr), (_newval), (_oldval)) - -inline int ExchangeInt(volatile int *ptr, int newval) -{ return WRAP_XCHG(int,AtomicSwap32,ptr,newval); } - -#ifdef _WIN64 -inline void *ExchangePtr(XchgPtr *ptr, void *newval) -{ return WRAP_XCHG(void*,AtomicSwap64,ptr,newval); } -#else -inline void *ExchangePtr(XchgPtr *ptr, void *newval) -{ return WRAP_XCHG(void*,AtomicSwap32,ptr,newval); } -#endif - - -#define ATOMIC(T) struct { T volatile value; } - -#define ATOMIC_INIT(_val, _newval) do { (_val)->value = (_newval); } while(0) -#define ATOMIC_INIT_STATIC(_newval) {(_newval)} - -#define ATOMIC_LOAD(_val) ((_val)->value) -#define ATOMIC_STORE(_val, _newval) do { \ - (_val)->value = (_newval); \ -} while(0) - -int _al_invalid_atomic_size(); /* not defined */ - -#define ATOMIC_ADD(T, _val, _incr) \ - ((sizeof(T)==4) ? WRAP_ADDSUB(T, AtomicAdd32, &(_val)->value, (_incr)) : \ - (T)_al_invalid_atomic_size()) -#define ATOMIC_SUB(T, _val, _decr) \ - ((sizeof(T)==4) ? WRAP_ADDSUB(T, AtomicSub32, &(_val)->value, (_decr)) : \ - (T)_al_invalid_atomic_size()) - -#define ATOMIC_EXCHANGE(T, _val, _newval) \ - ((sizeof(T)==4) ? WRAP_XCHG(T, AtomicSwap32, &(_val)->value, (_newval)) : \ - (sizeof(T)==8) ? WRAP_XCHG(T, AtomicSwap64, &(_val)->value, (_newval)) : \ - (T)_al_invalid_atomic_size()) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) \ - ((sizeof(T)==4) ? WRAP_CMPXCHG(T, CompareAndSwap32, &(_val)->value, (_newval), (_oldval)) : \ - (sizeof(T)==8) ? WRAP_CMPXCHG(T, CompareAndSwap64, &(_val)->value, (_newval), (_oldval)) : \ - (bool)_al_invalid_atomic_size()) - -#else - -#error "No atomic functions available on this platform!" - -#define ATOMIC(T) T - -#define ATOMIC_INIT_STATIC(_newval) (0) - -#define ATOMIC_LOAD_UNSAFE(_val) (0) -#define ATOMIC_STORE_UNSAFE(_val, _newval) ((void)0) - -#define ATOMIC_LOAD(_val) (0) -#define ATOMIC_STORE(_val, _newval) ((void)0) - -#define ATOMIC_ADD(T, _val, _incr) (0) -#define ATOMIC_SUB(T, _val, _decr) (0) - -#define ATOMIC_EXCHANGE(T, _val, _newval) (0) -#define ATOMIC_COMPARE_EXCHANGE_STRONG(T, _val, _oldval, _newval) (0) -#endif - -/* If no weak cmpxchg is provided (not all systems will have one), substitute a - * strong cmpxchg. */ -#ifndef ATOMIC_COMPARE_EXCHANGE_WEAK -#define ATOMIC_COMPARE_EXCHANGE_WEAK(a, b, c, d) ATOMIC_COMPARE_EXCHANGE_STRONG(a, b, c, d) -#endif - -/* This is *NOT* atomic, but is a handy utility macro to compare-and-swap non- - * atomic variables. */ -#define COMPARE_EXCHANGE(_val, _oldval, _newval) ((*(_val) == *(_oldval)) ? ((*(_val)=(_newval)),true) : ((*(_oldval)=*(_val)),false)) - - -typedef unsigned int uint; -typedef ATOMIC(uint) RefCount; - -inline void InitRef(RefCount *ptr, uint value) -{ ATOMIC_INIT(ptr, value); } -inline uint ReadRef(RefCount *ptr) -{ return ATOMIC_LOAD(ptr); } -inline uint IncrementRef(RefCount *ptr) -{ return ATOMIC_ADD(uint, ptr, 1)+1; } -inline uint DecrementRef(RefCount *ptr) -{ return ATOMIC_SUB(uint, ptr, 1)-1; } - -#ifdef __cplusplus -} -#endif - -#endif /* AL_ATOMIC_H */ diff --git a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/CMakeLists.txt b/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/CMakeLists.txt deleted file mode 100644 index a6707a3d..00000000 --- a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -project(alsoft-config) - -include_directories("${alsoft-config_BINARY_DIR}") - -# Need Qt 4.8.0 or newer for the iconset theme attribute to work -find_package(Qt4 4.8.0 COMPONENTS QtCore QtGui) -if(QT4_FOUND) - include(${QT_USE_FILE}) - - set(alsoft-config_SRCS main.cpp - mainwindow.cpp - ) - - set(alsoft-config_UIS mainwindow.ui) - QT4_WRAP_UI(UIS ${alsoft-config_UIS}) - - set(alsoft-config_MOCS mainwindow.h) - QT4_WRAP_CPP(MOCS ${alsoft-config_MOCS}) - - add_executable(alsoft-config ${alsoft-config_SRCS} ${UIS} ${RSCS} ${TRS} ${MOCS}) - target_link_libraries(alsoft-config ${QT_LIBRARIES}) - set_target_properties(alsoft-config PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${OpenAL_BINARY_DIR}) - - install(TARGETS alsoft-config - RUNTIME DESTINATION bin - LIBRARY DESTINATION "lib${LIB_SUFFIX}" - ARCHIVE DESTINATION "lib${LIB_SUFFIX}" - ) -endif() diff --git a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.cpp b/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.cpp deleted file mode 100644 index 1d5a3dcd..00000000 --- a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.cpp +++ /dev/null @@ -1,660 +0,0 @@ -#include -#include -#include -#include -#include "mainwindow.h" -#include "ui_mainwindow.h" - -namespace { -static const struct { - char backend_name[16]; - char menu_string[32]; -} backendMenuList[] = { -#ifdef Q_OS_WIN32 - { "mmdevapi", "Add MMDevAPI" }, - { "dsound", "Add DirectSound" }, - { "winmm", "Add Windows Multimedia" }, -#endif -#ifdef Q_OS_MAC - { "core", "Add CoreAudio" }, -#endif - { "pulse", "Add PulseAudio" }, -#ifdef Q_OS_UNIX - { "alsa", "Add ALSA" }, - { "oss", "Add OSS" }, - { "solaris", "Add Solaris" }, - { "sndio", "Add SndIO" }, - { "qsa", "Add QSA" }, -#endif - { "port", "Add PortAudio" }, - { "opensl", "Add OpenSL" }, - { "null", "Add Null Output" }, - { "wave", "Add Wave Writer" }, - { "", "" } -}; - -static QString getDefaultConfigName() -{ -#ifdef Q_OS_WIN32 - static const char fname[] = "alsoft.ini"; - QByteArray base = qgetenv("AppData"); -#else - static const char fname[] = "alsoft.conf"; - QByteArray base = qgetenv("XDG_CONFIG_HOME"); - if(base.isEmpty()) - { - base = qgetenv("HOME"); - if(base.isEmpty() == false) - base += "/.config"; - } -#endif - if(base.isEmpty() == false) - return base +'/'+ fname; - return fname; -} - -static QString getBaseDataPath() -{ -#ifdef Q_OS_WIN32 - QByteArray base = qgetenv("AppData"); -#else - QByteArray base = qgetenv("XDG_DATA_HOME"); - if(base.isEmpty()) - { - base = qgetenv("HOME"); - if(!base.isEmpty()) - base += "/.local/share"; - } -#endif - return base; -} - -static QStringList getAllDataPaths(QString append=QString()) -{ - QStringList list; - list.append(getBaseDataPath()); -#ifdef Q_OS_WIN32 - // TODO: Common AppData path -#else - QString paths = qgetenv("XDG_DATA_DIRS"); - if(paths.isEmpty()) - paths = "/usr/local/share/:/usr/share/"; - list += paths.split(QChar(':'), QString::SkipEmptyParts); -#endif - QStringList::iterator iter = list.begin(); - while(iter != list.end()) - { - if(iter->isEmpty()) - iter = list.erase(iter); - else - { - iter->append(append); - iter++; - } - } - return list; -} -} - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow), - mPeriodSizeValidator(NULL), - mPeriodCountValidator(NULL), - mSourceCountValidator(NULL), - mEffectSlotValidator(NULL), - mSourceSendValidator(NULL), - mSampleRateValidator(NULL), - mReverbBoostValidator(NULL) -{ - ui->setupUi(this); - - mPeriodSizeValidator = new QIntValidator(64, 8192, this); - ui->periodSizeEdit->setValidator(mPeriodSizeValidator); - mPeriodCountValidator = new QIntValidator(2, 16, this); - ui->periodCountEdit->setValidator(mPeriodCountValidator); - - mSourceCountValidator = new QIntValidator(0, 256, this); - ui->srcCountLineEdit->setValidator(mSourceCountValidator); - mEffectSlotValidator = new QIntValidator(0, 16, this); - ui->effectSlotLineEdit->setValidator(mEffectSlotValidator); - mSourceSendValidator = new QIntValidator(0, 4, this); - ui->srcSendLineEdit->setValidator(mSourceSendValidator); - mSampleRateValidator = new QIntValidator(8000, 192000, this); - ui->sampleRateCombo->lineEdit()->setValidator(mSampleRateValidator); - - mReverbBoostValidator = new QDoubleValidator(-12.0, +12.0, 1, this); - ui->reverbBoostEdit->setValidator(mReverbBoostValidator); - - connect(ui->actionLoad, SIGNAL(triggered()), this, SLOT(loadConfigFromFile())); - connect(ui->actionSave_As, SIGNAL(triggered()), this, SLOT(saveConfigAsFile())); - - connect(ui->applyButton, SIGNAL(clicked()), this, SLOT(saveCurrentConfig())); - - connect(ui->periodSizeSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodSizeEdit(int))); - connect(ui->periodSizeEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodSizeSlider())); - connect(ui->periodCountSlider, SIGNAL(valueChanged(int)), this, SLOT(updatePeriodCountEdit(int))); - connect(ui->periodCountEdit, SIGNAL(editingFinished()), this, SLOT(updatePeriodCountSlider())); - - connect(ui->hrtfAddButton, SIGNAL(clicked()), this, SLOT(addHrtfFile())); - connect(ui->hrtfRemoveButton, SIGNAL(clicked()), this, SLOT(removeHrtfFile())); - connect(ui->hrtfFileList, SIGNAL(itemSelectionChanged()), this, SLOT(updateHrtfRemoveButton())); - - ui->enabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->enabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showEnabledBackendMenu(QPoint))); - - ui->disabledBackendList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->disabledBackendList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDisabledBackendMenu(QPoint))); - - connect(ui->reverbBoostSlider, SIGNAL(valueChanged(int)), this, SLOT(updateReverbBoostEdit(int))); - connect(ui->reverbBoostEdit, SIGNAL(textEdited(QString)), this, SLOT(updateReverbBoostSlider(QString))); - - loadConfig(getDefaultConfigName()); -} - -MainWindow::~MainWindow() -{ - delete ui; - delete mPeriodSizeValidator; - delete mPeriodCountValidator; - delete mSourceCountValidator; - delete mEffectSlotValidator; - delete mSourceSendValidator; - delete mSampleRateValidator; - delete mReverbBoostValidator; -} - -void MainWindow::loadConfigFromFile() -{ - QString fname = QFileDialog::getOpenFileName(this, tr("Select Files")); - if(fname.isEmpty() == false) - loadConfig(fname); -} - -void MainWindow::loadConfig(const QString &fname) -{ - QSettings settings(fname, QSettings::IniFormat); - - QString sampletype = settings.value("sample-type").toString(); - ui->sampleFormatCombo->setCurrentIndex(0); - if(sampletype.isEmpty() == false) - { - for(int i = 1;i < ui->sampleFormatCombo->count();i++) - { - QString item = ui->sampleFormatCombo->itemText(i); - if(item.startsWith(sampletype)) - { - ui->sampleFormatCombo->setCurrentIndex(i); - break; - } - } - } - - QString channelconfig = settings.value("channels").toString(); - ui->channelConfigCombo->setCurrentIndex(0); - if(channelconfig.isEmpty() == false) - { - for(int i = 1;i < ui->channelConfigCombo->count();i++) - { - QString item = ui->channelConfigCombo->itemText(i); - if(item.startsWith(channelconfig)) - { - ui->channelConfigCombo->setCurrentIndex(i); - break; - } - } - } - - QString srate = settings.value("frequency").toString(); - if(srate.isEmpty()) - ui->sampleRateCombo->setCurrentIndex(0); - else - { - ui->sampleRateCombo->lineEdit()->clear(); - ui->sampleRateCombo->lineEdit()->insert(srate); - } - - ui->srcCountLineEdit->clear(); - ui->srcCountLineEdit->insert(settings.value("sources").toString()); - ui->effectSlotLineEdit->clear(); - ui->effectSlotLineEdit->insert(settings.value("slots").toString()); - ui->srcSendLineEdit->clear(); - ui->srcSendLineEdit->insert(settings.value("sends").toString()); - - QString resampler = settings.value("resampler").toString().trimmed(); - if(resampler.isEmpty()) - ui->resamplerComboBox->setCurrentIndex(0); - else - { - for(int i = 1;i < ui->resamplerComboBox->count();i++) - { - QString item = ui->resamplerComboBox->itemText(i); - int end = item.indexOf(' '); - if(end < 0) end = item.size(); - if(resampler.size() == end && resampler.compare(item.leftRef(end), Qt::CaseInsensitive) == 0) - { - ui->resamplerComboBox->setCurrentIndex(i); - break; - } - } - } - - int periodsize = settings.value("period_size").toInt(); - ui->periodSizeEdit->clear(); - if(periodsize >= 64) - { - ui->periodSizeEdit->insert(QString::number(periodsize)); - updatePeriodSizeSlider(); - } - - int periodcount = settings.value("periods").toInt(); - ui->periodCountEdit->clear(); - if(periodcount >= 2) - { - ui->periodCountEdit->insert(QString::number(periodcount)); - updatePeriodCountSlider(); - } - - QStringList disabledCpuExts = settings.value("disable-cpu-exts").toStringList(); - if(disabledCpuExts.size() == 1) - disabledCpuExts = disabledCpuExts[0].split(QChar(',')); - std::transform(disabledCpuExts.begin(), disabledCpuExts.end(), - disabledCpuExts.begin(), std::mem_fun_ref(&QString::trimmed)); - ui->enableSSECheckBox->setChecked(!disabledCpuExts.contains("sse", Qt::CaseInsensitive)); - ui->enableSSE2CheckBox->setChecked(!disabledCpuExts.contains("sse2", Qt::CaseInsensitive)); - ui->enableSSE41CheckBox->setChecked(!disabledCpuExts.contains("sse4.1", Qt::CaseInsensitive)); - ui->enableNeonCheckBox->setChecked(!disabledCpuExts.contains("neon", Qt::CaseInsensitive)); - - if(settings.value("hrtf").toString() == QString()) - ui->hrtfEnableButton->setChecked(true); - else - { - if(settings.value("hrtf", true).toBool()) - ui->hrtfForceButton->setChecked(true); - else - ui->hrtfDisableButton->setChecked(true); - } - - QStringList hrtf_tables = settings.value("hrtf_tables").toStringList(); - if(hrtf_tables.size() == 1) - hrtf_tables = hrtf_tables[0].split(QChar(',')); - std::transform(hrtf_tables.begin(), hrtf_tables.end(), - hrtf_tables.begin(), std::mem_fun_ref(&QString::trimmed)); - ui->hrtfFileList->clear(); - ui->hrtfFileList->addItems(hrtf_tables); - updateHrtfRemoveButton(); - - ui->enabledBackendList->clear(); - ui->disabledBackendList->clear(); - QStringList drivers = settings.value("drivers").toStringList(); - if(drivers.size() == 0) - ui->backendCheckBox->setChecked(true); - else - { - if(drivers.size() == 1) - drivers = drivers[0].split(QChar(',')); - std::transform(drivers.begin(), drivers.end(), - drivers.begin(), std::mem_fun_ref(&QString::trimmed)); - - bool lastWasEmpty = false; - foreach(const QString &backend, drivers) - { - lastWasEmpty = backend.isEmpty(); - if(!backend.startsWith(QChar('-')) && !lastWasEmpty) - ui->enabledBackendList->addItem(backend); - else if(backend.size() > 1) - ui->disabledBackendList->addItem(backend.right(backend.size()-1)); - } - ui->backendCheckBox->setChecked(lastWasEmpty); - } - - QString defaultreverb = settings.value("default-reverb").toString().toLower(); - ui->defaultReverbComboBox->setCurrentIndex(0); - if(defaultreverb.isEmpty() == false) - { - for(int i = 0;i < ui->defaultReverbComboBox->count();i++) - { - if(defaultreverb.compare(ui->defaultReverbComboBox->itemText(i).toLower()) == 0) - { - ui->defaultReverbComboBox->setCurrentIndex(i); - break; - } - } - } - - ui->emulateEaxCheckBox->setChecked(settings.value("reverb/emulate-eax", false).toBool()); - ui->reverbBoostEdit->clear(); - ui->reverbBoostEdit->insert(settings.value("reverb/boost").toString()); - - QStringList excludefx = settings.value("excludefx").toStringList(); - if(excludefx.size() == 1) - excludefx = excludefx[0].split(QChar(',')); - std::transform(excludefx.begin(), excludefx.end(), - excludefx.begin(), std::mem_fun_ref(&QString::trimmed)); - ui->enableEaxReverbCheck->setChecked(!excludefx.contains("eaxreverb", Qt::CaseInsensitive)); - ui->enableStdReverbCheck->setChecked(!excludefx.contains("reverb", Qt::CaseInsensitive)); - ui->enableChorusCheck->setChecked(!excludefx.contains("chorus", Qt::CaseInsensitive)); - ui->enableCompressorCheck->setChecked(!excludefx.contains("compressor", Qt::CaseInsensitive)); - ui->enableDistortionCheck->setChecked(!excludefx.contains("distortion", Qt::CaseInsensitive)); - ui->enableEchoCheck->setChecked(!excludefx.contains("echo", Qt::CaseInsensitive)); - ui->enableEqualizerCheck->setChecked(!excludefx.contains("equalizer", Qt::CaseInsensitive)); - ui->enableFlangerCheck->setChecked(!excludefx.contains("flanger", Qt::CaseInsensitive)); - ui->enableModulatorCheck->setChecked(!excludefx.contains("modulator", Qt::CaseInsensitive)); - ui->enableDedicatedCheck->setChecked(!excludefx.contains("dedicated", Qt::CaseInsensitive)); -} - -void MainWindow::saveCurrentConfig() -{ - saveConfig(getDefaultConfigName()); - QMessageBox::information(this, tr("Information"), - tr("Applications using OpenAL need to be restarted for changes to take effect.")); -} - -void MainWindow::saveConfigAsFile() -{ - QString fname = QFileDialog::getOpenFileName(this, tr("Select Files")); - if(fname.isEmpty() == false) - saveConfig(fname); -} - -void MainWindow::saveConfig(const QString &fname) const -{ - QSettings settings(fname, QSettings::IniFormat); - - /* HACK: Compound any stringlist values into a comma-separated string. */ - QStringList allkeys = settings.allKeys(); - foreach(const QString &key, allkeys) - { - QStringList vals = settings.value(key).toStringList(); - if(vals.size() > 1) - settings.setValue(key, vals.join(QChar(','))); - } - - QString str = ui->sampleFormatCombo->currentText(); - str.truncate(str.indexOf('-')); - settings.setValue("sample-type", str.trimmed()); - - str = ui->channelConfigCombo->currentText(); - str.truncate(str.indexOf('-')); - settings.setValue("channels", str.trimmed()); - - uint rate = ui->sampleRateCombo->currentText().toUInt(); - if(rate == 0) - settings.setValue("frequency", QString()); - else - settings.setValue("frequency", rate); - - settings.setValue("period_size", ui->periodSizeEdit->text()); - settings.setValue("periods", ui->periodCountEdit->text()); - - settings.setValue("sources", ui->srcCountLineEdit->text()); - settings.setValue("slots", ui->effectSlotLineEdit->text()); - - if(ui->resamplerComboBox->currentIndex() == 0) - settings.setValue("resampler", QString()); - else - { - str = ui->resamplerComboBox->currentText(); - settings.setValue("resampler", str.split(' ').first().toLower()); - } - - QStringList strlist; - if(!ui->enableSSECheckBox->isChecked()) - strlist.append("sse"); - if(!ui->enableSSE2CheckBox->isChecked()) - strlist.append("sse2"); - if(!ui->enableSSE41CheckBox->isChecked()) - strlist.append("sse4.1"); - if(!ui->enableNeonCheckBox->isChecked()) - strlist.append("neon"); - settings.setValue("disable-cpu-exts", strlist.join(QChar(','))); - - if(ui->hrtfForceButton->isChecked()) - settings.setValue("hrtf", "true"); - else if(ui->hrtfDisableButton->isChecked()) - settings.setValue("hrtf", "false"); - else - settings.setValue("hrtf", QString()); - - strlist.clear(); - QList items = ui->hrtfFileList->findItems("*", Qt::MatchWildcard); - foreach(const QListWidgetItem *item, items) - strlist.append(item->text()); - settings.setValue("hrtf_tables", strlist.join(QChar(','))); - - strlist.clear(); - items = ui->enabledBackendList->findItems("*", Qt::MatchWildcard); - foreach(const QListWidgetItem *item, items) - strlist.append(item->text()); - items = ui->disabledBackendList->findItems("*", Qt::MatchWildcard); - foreach(const QListWidgetItem *item, items) - strlist.append(QChar('-')+item->text()); - if(strlist.size() == 0 && !ui->backendCheckBox->isChecked()) - strlist.append("-all"); - else if(ui->backendCheckBox->isChecked()) - strlist.append(QString()); - settings.setValue("drivers", strlist.join(QChar(','))); - - // TODO: Remove check when we can properly match global values. - if(ui->defaultReverbComboBox->currentIndex() == 0) - settings.setValue("default-reverb", QString()); - else - { - str = ui->defaultReverbComboBox->currentText().toLower(); - settings.setValue("default-reverb", str); - } - - if(ui->emulateEaxCheckBox->isChecked()) - settings.setValue("reverb/emulate-eax", "true"); - else - settings.setValue("reverb/emulate-eax", QString()/*"false"*/); - - // TODO: Remove check when we can properly match global values. - if(ui->reverbBoostSlider->sliderPosition() == 0) - settings.setValue("reverb/boost", QString()); - else - settings.setValue("reverb/boost", ui->reverbBoostEdit->text()); - - strlist.clear(); - if(!ui->enableEaxReverbCheck->isChecked()) - strlist.append("eaxreverb"); - if(!ui->enableStdReverbCheck->isChecked()) - strlist.append("reverb"); - if(!ui->enableChorusCheck->isChecked()) - strlist.append("chorus"); - if(!ui->enableDistortionCheck->isChecked()) - strlist.append("distortion"); - if(!ui->enableCompressorCheck->isChecked()) - strlist.append("compressor"); - if(!ui->enableEchoCheck->isChecked()) - strlist.append("echo"); - if(!ui->enableEqualizerCheck->isChecked()) - strlist.append("equalizer"); - if(!ui->enableFlangerCheck->isChecked()) - strlist.append("flanger"); - if(!ui->enableModulatorCheck->isChecked()) - strlist.append("modulator"); - if(!ui->enableDedicatedCheck->isChecked()) - strlist.append("dedicated"); - settings.setValue("excludefx", strlist.join(QChar(','))); - - /* Remove empty keys - * FIXME: Should only remove keys whose value matches the globally-specified value. - */ - allkeys = settings.allKeys(); - foreach(const QString &key, allkeys) - { - str = settings.value(key).toString(); - if(str == QString()) - settings.remove(key); - } -} - - -void MainWindow::updatePeriodSizeEdit(int size) -{ - ui->periodSizeEdit->clear(); - if(size >= 64) - { - size = (size+32)&~0x3f; - ui->periodSizeEdit->insert(QString::number(size)); - } -} - -void MainWindow::updatePeriodSizeSlider() -{ - int pos = ui->periodSizeEdit->text().toInt(); - if(pos >= 64) - { - if(pos > 8192) - pos = 8192; - ui->periodSizeSlider->setSliderPosition(pos); - } -} - -void MainWindow::updatePeriodCountEdit(int count) -{ - ui->periodCountEdit->clear(); - if(count >= 2) - ui->periodCountEdit->insert(QString::number(count)); -} - -void MainWindow::updatePeriodCountSlider() -{ - int pos = ui->periodCountEdit->text().toInt(); - if(pos < 2) - pos = 0; - else if(pos > 16) - pos = 16; - ui->periodCountSlider->setSliderPosition(pos); -} - - -void MainWindow::addHrtfFile() -{ - const QStringList datapaths = getAllDataPaths("/openal/hrtf"); - QStringList fnames = QFileDialog::getOpenFileNames(this, tr("Select Files"), - datapaths.empty() ? QString() : datapaths[0], - "HRTF Datasets(*.mhr);;All Files(*.*)"); - if(fnames.isEmpty() == false) - { - for(QStringList::iterator iter = fnames.begin();iter != fnames.end();iter++) - { - QStringList::const_iterator path = datapaths.constBegin(); - for(;path != datapaths.constEnd();path++) - { - QDir hrtfdir(*path); - if(!hrtfdir.isAbsolute()) - continue; - - const QString relname = hrtfdir.relativeFilePath(*iter); - if(!relname.startsWith("..")) - { - // If filename is within this path, use the relative pathname - ui->hrtfFileList->addItem(relname); - break; - } - } - if(path == datapaths.constEnd()) - { - // Filename is not within any data path, use the absolute pathname - ui->hrtfFileList->addItem(*iter); - } - } - } -} - -void MainWindow::removeHrtfFile() -{ - QList selected = ui->hrtfFileList->selectedItems(); - foreach(QListWidgetItem *item, selected) - delete item; -} - -void MainWindow::updateHrtfRemoveButton() -{ - ui->hrtfRemoveButton->setEnabled(ui->hrtfFileList->selectedItems().size() != 0); -} - -void MainWindow::showEnabledBackendMenu(QPoint pt) -{ - QMap actionMap; - - pt = ui->enabledBackendList->mapToGlobal(pt); - - QMenu ctxmenu; - QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove"); - if(ui->enabledBackendList->selectedItems().size() == 0) - removeAction->setEnabled(false); - ctxmenu.addSeparator(); - for(size_t i = 0;backendMenuList[i].backend_name[0];i++) - { - QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string); - actionMap[action] = backendMenuList[i].backend_name; - if(ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 || - ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0) - action->setEnabled(false); - } - - QAction *gotAction = ctxmenu.exec(pt); - if(gotAction == removeAction) - { - QList selected = ui->enabledBackendList->selectedItems(); - foreach(QListWidgetItem *item, selected) - delete item; - } - else if(gotAction != NULL) - { - QMap::const_iterator iter = actionMap.find(gotAction); - if(iter != actionMap.end()) - ui->enabledBackendList->addItem(iter.value()); - } -} - -void MainWindow::showDisabledBackendMenu(QPoint pt) -{ - QMap actionMap; - - pt = ui->disabledBackendList->mapToGlobal(pt); - - QMenu ctxmenu; - QAction *removeAction = ctxmenu.addAction(QIcon::fromTheme("list-remove"), "Remove"); - if(ui->disabledBackendList->selectedItems().size() == 0) - removeAction->setEnabled(false); - ctxmenu.addSeparator(); - for(size_t i = 0;backendMenuList[i].backend_name[0];i++) - { - QAction *action = ctxmenu.addAction(backendMenuList[i].menu_string); - actionMap[action] = backendMenuList[i].backend_name; - if(ui->disabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0 || - ui->enabledBackendList->findItems(backendMenuList[i].backend_name, Qt::MatchFixedString).size() != 0) - action->setEnabled(false); - } - - QAction *gotAction = ctxmenu.exec(pt); - if(gotAction == removeAction) - { - QList selected = ui->disabledBackendList->selectedItems(); - foreach(QListWidgetItem *item, selected) - delete item; - } - else if(gotAction != NULL) - { - QMap::const_iterator iter = actionMap.find(gotAction); - if(iter != actionMap.end()) - ui->disabledBackendList->addItem(iter.value()); - } -} - -void MainWindow::updateReverbBoostEdit(int value) -{ - ui->reverbBoostEdit->clear(); - if(value != 0) - ui->reverbBoostEdit->insert(QString::number(value/10.0, 'f', 1)); -} - -void MainWindow::updateReverbBoostSlider(QString value) -{ - int pos = int(value.toFloat()*10.0f); - ui->reverbBoostSlider->setSliderPosition(pos); -} diff --git a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.ui b/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.ui deleted file mode 100644 index 3c92abf6..00000000 --- a/love/src/jni/openal-soft-1.17.0/utils/alsoft-config/mainwindow.ui +++ /dev/null @@ -1,1464 +0,0 @@ - - - MainWindow - - - - 0 - 0 - 564 - 454 - - - - OpenAL Soft Configuration - - - - - - - - - - - 470 - 405 - 81 - 25 - - - - Apply - - - - - - - - - - - 10 - 0 - 541 - 401 - - - - 0 - - - - Playback - - - - - 120 - 20 - 188 - 22 - - - - The output sample type. Currently, all mixing is done with 32-bit -float and converted to the output sample type as needed. - - - QComboBox::AdjustToContents - - - - - Autodetect - - - - - - int8 - signed 8-bit int - - - - - uint8 - unsigned 8-bit int - - - - - int16 - signed 16-bit int - - - - - uint16 - unsigned 16-bit int - - - - - int32 - signed 32-bit int - - - - - uint32 - unsigned 32-bit int - - - - - float32 - 32-bit float - - - - - - - 10 - 20 - 101 - 21 - - - - Sample Format: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 10 - 50 - 101 - 21 - - - - Channels: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 120 - 50 - 227 - 22 - - - - The output channel configuration. Note that not all backends -can properly detect the channel configuration and may default -to stereo output. - - - QComboBox::AdjustToContents - - - - - Autodetect - - - - - - mono - 1-channel Mono - - - - - stereo - 2-channel Stereo - - - - - quad - 4-channel Quadraphonic - - - - - surround51 - 5.1 Surround Sound - - - - - surround61 - 6.1 Surround Sound - - - - - surround71 - 7.1 Surround Sound - - - - - - - 120 - 80 - 111 - 22 - - - - The playback/mixing sample rate. - - - true - - - QComboBox::NoInsert - - - QComboBox::AdjustToContents - - - - - Autodetect - - - - - - 96000 - - - - - 48000 - - - - - 44100 - - - - - 32000 - - - - - 22050 - - - - - 16000 - - - - - 11025 - - - - - 8000 - - - - - - - 10 - 80 - 101 - 21 - - - - Sample Rate: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 10 - 200 - 511 - 161 - - - - HRTF (Stereo only) - - - - - 20 - 30 - 71 - 21 - - - - Allows applications to request HRTF mixing. - - - Enable - - - true - - - - - - 20 - 50 - 71 - 21 - - - - Does not allow HRTF mixing, even when requested. - - - Disable - - - - - - 20 - 70 - 71 - 21 - - - - Attempts to force HRTF mixing, even if applications request not -to do it. This may override the channel configuration and -sample rate. - - - Force - - - - - - 110 - 30 - 301 - 121 - - - - A list of files containing HRTF data sets. The listed data sets -are used in place of the default sets. The filenames may -contain these markers, which will be replaced as needed: -%r - Device sampling rate -%% - Percent sign (%) - - - false - - - QAbstractItemView::InternalMove - - - true - - - QAbstractItemView::ExtendedSelection - - - Qt::ElideNone - - - - - - 419 - 30 - 81 - 25 - - - - Add... - - - - - - - - false - - - - - - 419 - 60 - 81 - 25 - - - - Remove - - - - - - - - - - - - 10 - 110 - 511 - 91 - - - - Buffer Metrics - - - - - 260 - 20 - 241 - 51 - - - - The number of update periods. Higher values create a larger -mix ahead, which helps protect against skips when the CPU is -under load, but increases the delay between a sound getting -mixed and being heard. - - - - - 20 - 0 - 201 - 21 - - - - Period Count - - - Qt::AlignCenter - - - - - - 70 - 20 - 160 - 23 - - - - 1 - - - 16 - - - 1 - - - 2 - - - 1 - - - true - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 1 - - - - - - 20 - 20 - 51 - 22 - - - - 4 - - - - - - - 10 - 20 - 241 - 51 - - - - The update period size, in sample frames. This is the number of -frames needed for each mixing update. - - - - - 60 - 20 - 160 - 23 - - - - 0 - - - 8192 - - - 64 - - - 1024 - - - 0 - - - true - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 512 - - - - - - 10 - 0 - 201 - 21 - - - - Period Samples - - - Qt::AlignCenter - - - - - - 10 - 20 - 51 - 22 - - - - 1024 - - - - - - - - Resources - - - - - 190 - 20 - 51 - 22 - - - - The maximum number of allocatable sources. Lower values may -help for systems with apps that try to play more sounds than -the CPU can handle. - - - - - - 3 - - - true - - - 256 - - - - - - 10 - 20 - 171 - 21 - - - - Number of Sound Sources: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 10 - 50 - 171 - 21 - - - - Number of Effect Slots: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 190 - 50 - 51 - 22 - - - - The maximum number of Auxiliary Effect Slots an app can -create. A slot can use a non-negligible amount of CPU time if -an effect is set on it even if no sources are feeding it, so this -may help when apps use more than the system can handle. - - - - - - 1 - - - true - - - 4 - - - - - - 10 - 80 - 171 - 21 - - - - Number of Source Sends: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 190 - 80 - 51 - 22 - - - - The number of auxiliary sends per source. When not specified, -it allows the app to request how many it wants. The maximum -value currently possible is 4. - - - 1 - - - Auto - - - - - - 30 - 120 - 71 - 21 - - - - Resampler: - - - - - - 110 - 120 - 185 - 22 - - - - The resampling method used when mixing sources. - - - QComboBox::AdjustToContents - - - - - Default - - - - - - Point (low quality, fast) - - - - - Linear (basic quality, fast) - - - - - Cubic Spline (good quality) - - - - - - - 10 - 150 - 511 - 91 - - - - Enables use of specific CPU extensions. Certain methods may -utilize CPU extensions when detected, and disabling these can -be useful for preventing those extensions from being used. - - - CPU Extensions - - - - - 180 - 20 - 71 - 31 - - - - SSE - - - true - - - - - - 180 - 50 - 71 - 31 - - - - SSE2 - - - true - - - - - - 260 - 50 - 71 - 31 - - - - Neon - - - true - - - - - - 260 - 20 - 71 - 31 - - - - SSE4.1 - - - true - - - - - - - Backends - - - - - 170 - 200 - 161 - 21 - - - - When checked, allows all other available backends not listed in the priority or disabled lists. - - - Allow Other Backends - - - true - - - - - - 40 - 40 - 191 - 151 - - - - The backend driver list order. Unknown backends and -duplicated names are ignored. - - - QAbstractItemView::InternalMove - - - - - - 40 - 20 - 191 - 20 - - - - Priority Backends: - - - - - - 270 - 40 - 191 - 151 - - - - Disabled backend driver list. - - - - - - 270 - 20 - 191 - 20 - - - - Disabled Backends: - - - - - - Effects - - - - - 10 - 60 - 161 - 21 - - - - Uses a simpler reverb method to emulate the EAX reverb -effect. This may slightly improve performance at the cost of -some quality. - - - Qt::RightToLeft - - - Emulate EAX Reverb: - - - - - - 10 - 100 - 511 - 61 - - - - Global amplification for reverb output, expressed in decibels. -+6 will be a scale of (approximately) 2x, +12 will be a scale of -4x, etc. Similarly, -6 will be about half, and -12 about 1/4th. A -value of 0 means no change. - - - Reverb Boost - - - - - 10 - 30 - 391 - 23 - - - - - - - -120 - - - 120 - - - Qt::Horizontal - - - QSlider::TicksBelow - - - 10 - - - - - - 410 - 30 - 51 - 22 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0.0 - - - - - - 460 - 30 - 31 - 21 - - - - dB - - - - - - - 10 - 170 - 511 - 191 - - - - Specifies which effects apps can recognize. Disabling effects -can help for apps that try to use ones that are too intensive -for the system to handle. - - - Enabled Effects - - - - - 70 - 30 - 131 - 21 - - - - EAX Reverb - - - true - - - - - - 70 - 60 - 131 - 21 - - - - Standard Reverb - - - true - - - - - - 70 - 90 - 131 - 21 - - - - Chorus - - - true - - - - - - 70 - 150 - 131 - 21 - - - - Distortion - - - true - - - - - - 320 - 30 - 131 - 21 - - - - Echo - - - true - - - - - - 320 - 60 - 131 - 21 - - - - Equalizer - - - true - - - - - - 320 - 90 - 131 - 21 - - - - Flanger - - - true - - - - - - 320 - 120 - 131 - 21 - - - - Ring Modulator - - - true - - - - - - 320 - 150 - 131 - 21 - - - - Enables both the Dedicated Dialog and Dedicated LFE effects -added by the ALC_EXT_DEDICATED extension. - - - Dedicated ... - - - true - - - - - - 70 - 120 - 111 - 21 - - - - Compressor - - - true - - - - - - - 10 - 20 - 141 - 21 - - - - Default Reverb Effect: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - 160 - 20 - 131 - 22 - - - - QComboBox::AdjustToContents - - - - None - - - - - Generic - - - - - PaddedCell - - - - - Room - - - - - Bathroom - - - - - Livingroom - - - - - Stoneroom - - - - - Auditorium - - - - - ConcertHall - - - - - Cave - - - - - Arena - - - - - Hangar - - - - - CarpetedHallway - - - - - Hallway - - - - - StoneCorridor - - - - - Alley - - - - - Forest - - - - - City - - - - - Mountains - - - - - Quarry - - - - - Plain - - - - - ParkingLot - - - - - SewerPipe - - - - - Underwater - - - - - Drugged - - - - - Dizzy - - - - - Psychotic - - - - - - - - - - 0 - 0 - 564 - 19 - - - - - &File - - - - - - - - - - - - - - - - &Quit - - - - - - - - - - Save &As... - - - Save Configuration As - - - - - - - - - - &Load... - - - Load Configuration File - - - - - - - - actionQuit - activated() - MainWindow - close() - - - -1 - -1 - - - 267 - 181 - - - - - - ShowHRTFContextMenu(QPoint) - - diff --git a/love/src/jni/openal-soft-1.17.0/utils/makehrtf.c b/love/src/jni/openal-soft-1.17.0/utils/makehrtf.c deleted file mode 100644 index 0a1bd043..00000000 --- a/love/src/jni/openal-soft-1.17.0/utils/makehrtf.c +++ /dev/null @@ -1,2749 +0,0 @@ -/* - * HRTF utility for producing and demonstrating the process of creating an - * OpenAL Soft compatible HRIR data set. - * - * Copyright (C) 2011-2014 Christopher Fitzgerald - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Or visit: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - * - * -------------------------------------------------------------------------- - * - * A big thanks goes out to all those whose work done in the field of - * binaural sound synthesis using measured HRTFs makes this utility and the - * OpenAL Soft implementation possible. - * - * The algorithm for diffuse-field equalization was adapted from the work - * done by Rio Emmanuel and Larcher Veronique of IRCAM and Bill Gardner of - * MIT Media Laboratory. It operates as follows: - * - * 1. Take the FFT of each HRIR and only keep the magnitude responses. - * 2. Calculate the diffuse-field power-average of all HRIRs weighted by - * their contribution to the total surface area covered by their - * measurement. - * 3. Take the diffuse-field average and limit its magnitude range. - * 4. Equalize the responses by using the inverse of the diffuse-field - * average. - * 5. Reconstruct the minimum-phase responses. - * 5. Zero the DC component. - * 6. IFFT the result and truncate to the desired-length minimum-phase FIR. - * - * The spherical head algorithm for calculating propagation delay was adapted - * from the paper: - * - * Modeling Interaural Time Difference Assuming a Spherical Head - * Joel David Miller - * Music 150, Musical Acoustics, Stanford University - * December 2, 2001 - * - * The formulae for calculating the Kaiser window metrics are from the - * the textbook: - * - * Discrete-Time Signal Processing - * Alan V. Oppenheim and Ronald W. Schafer - * Prentice-Hall Signal Processing Series - * 1999 - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#ifdef HAVE_STRINGS_H -#include -#endif - -// Rely (if naively) on OpenAL's header for the types used for serialization. -#include "AL/al.h" -#include "AL/alext.h" - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - -#ifndef HUGE_VAL -#define HUGE_VAL (1.0 / 0.0) -#endif - -// The epsilon used to maintain signal stability. -#define EPSILON (1e-15) - -// Constants for accessing the token reader's ring buffer. -#define TR_RING_BITS (16) -#define TR_RING_SIZE (1 << TR_RING_BITS) -#define TR_RING_MASK (TR_RING_SIZE - 1) - -// The token reader's load interval in bytes. -#define TR_LOAD_SIZE (TR_RING_SIZE >> 2) - -// The maximum identifier length used when processing the data set -// definition. -#define MAX_IDENT_LEN (16) - -// The maximum path length used when processing filenames. -#define MAX_PATH_LEN (256) - -// The limits for the sample 'rate' metric in the data set definition and for -// resampling. -#define MIN_RATE (32000) -#define MAX_RATE (96000) - -// The limits for the HRIR 'points' metric in the data set definition. -#define MIN_POINTS (16) -#define MAX_POINTS (8192) - -// The limits to the number of 'azimuths' listed in the data set definition. -#define MIN_EV_COUNT (5) -#define MAX_EV_COUNT (128) - -// The limits for each of the 'azimuths' listed in the data set definition. -#define MIN_AZ_COUNT (1) -#define MAX_AZ_COUNT (128) - -// The limits for the listener's head 'radius' in the data set definition. -#define MIN_RADIUS (0.05) -#define MAX_RADIUS (0.15) - -// The limits for the 'distance' from source to listener in the definition -// file. -#define MIN_DISTANCE (0.5) -#define MAX_DISTANCE (2.5) - -// The maximum number of channels that can be addressed for a WAVE file -// source listed in the data set definition. -#define MAX_WAVE_CHANNELS (65535) - -// The limits to the byte size for a binary source listed in the definition -// file. -#define MIN_BIN_SIZE (2) -#define MAX_BIN_SIZE (4) - -// The minimum number of significant bits for binary sources listed in the -// data set definition. The maximum is calculated from the byte size. -#define MIN_BIN_BITS (16) - -// The limits to the number of significant bits for an ASCII source listed in -// the data set definition. -#define MIN_ASCII_BITS (16) -#define MAX_ASCII_BITS (32) - -// The limits to the FFT window size override on the command line. -#define MIN_FFTSIZE (512) -#define MAX_FFTSIZE (16384) - -// The limits to the equalization range limit on the command line. -#define MIN_LIMIT (2.0) -#define MAX_LIMIT (120.0) - -// The limits to the truncation window size on the command line. -#define MIN_TRUNCSIZE (8) -#define MAX_TRUNCSIZE (128) - -// The limits to the custom head radius on the command line. -#define MIN_CUSTOM_RADIUS (0.05) -#define MAX_CUSTOM_RADIUS (0.15) - -// The truncation window size must be a multiple of the below value to allow -// for vectorized convolution. -#define MOD_TRUNCSIZE (8) - -// The defaults for the command line options. -#define DEFAULT_EQUALIZE (1) -#define DEFAULT_SURFACE (1) -#define DEFAULT_LIMIT (24.0) -#define DEFAULT_TRUNCSIZE (32) -#define DEFAULT_HEAD_MODEL (HM_DATASET) -#define DEFAULT_CUSTOM_RADIUS (0.0) - -// The four-character-codes for RIFF/RIFX WAVE file chunks. -#define FOURCC_RIFF (0x46464952) // 'RIFF' -#define FOURCC_RIFX (0x58464952) // 'RIFX' -#define FOURCC_WAVE (0x45564157) // 'WAVE' -#define FOURCC_FMT (0x20746D66) // 'fmt ' -#define FOURCC_DATA (0x61746164) // 'data' -#define FOURCC_LIST (0x5453494C) // 'LIST' -#define FOURCC_WAVL (0x6C766177) // 'wavl' -#define FOURCC_SLNT (0x746E6C73) // 'slnt' - -// The supported wave formats. -#define WAVE_FORMAT_PCM (0x0001) -#define WAVE_FORMAT_IEEE_FLOAT (0x0003) -#define WAVE_FORMAT_EXTENSIBLE (0xFFFE) - -// The maximum propagation delay value supported by OpenAL Soft. -#define MAX_HRTD (63.0) - -// The OpenAL Soft HRTF format marker. It stands for minimum-phase head -// response protocol 01. -#define MHR_FORMAT ("MinPHR01") - -// Byte order for the serialization routines. -enum ByteOrderT { - BO_NONE = 0, - BO_LITTLE , - BO_BIG -}; - -// Source format for the references listed in the data set definition. -enum SourceFormatT { - SF_NONE = 0, - SF_WAVE , // RIFF/RIFX WAVE file. - SF_BIN_LE , // Little-endian binary file. - SF_BIN_BE , // Big-endian binary file. - SF_ASCII // ASCII text file. -}; - -// Element types for the references listed in the data set definition. -enum ElementTypeT { - ET_NONE = 0, - ET_INT , // Integer elements. - ET_FP // Floating-point elements. -}; - -// Head model used for calculating the impulse delays. -enum HeadModelT { - HM_NONE = 0, - HM_DATASET , // Measure the onset from the dataset. - HM_SPHERE // Calculate the onset using a spherical head model. -}; - -// Desired output format from the command line. -enum OutputFormatT { - OF_NONE = 0, - OF_MHR , // OpenAL Soft MHR data set file. - OF_TABLE // OpenAL Soft built-in table file (used when compiling). -}; - -// Unsigned integer type. -typedef unsigned int uint; - -// Serialization types. The trailing digit indicates the number of bits. -typedef ALubyte uint8; - -typedef ALint int32; -typedef ALuint uint32; -typedef ALuint64SOFT uint64; - -typedef enum ByteOrderT ByteOrderT; -typedef enum SourceFormatT SourceFormatT; -typedef enum ElementTypeT ElementTypeT; -typedef enum HeadModelT HeadModelT; -typedef enum OutputFormatT OutputFormatT; - -typedef struct TokenReaderT TokenReaderT; -typedef struct SourceRefT SourceRefT; -typedef struct HrirDataT HrirDataT; -typedef struct ResamplerT ResamplerT; - -// Token reader state for parsing the data set definition. -struct TokenReaderT { - FILE * mFile; - const char * mName; - uint mLine, - mColumn; - char mRing [TR_RING_SIZE]; - size_t mIn, - mOut; -}; - -// Source reference state used when loading sources. -struct SourceRefT { - SourceFormatT mFormat; - ElementTypeT mType; - uint mSize; - int mBits; - uint mChannel, - mSkip, - mOffset; - char mPath [MAX_PATH_LEN + 1]; -}; - -// The HRIR metrics and data set used when loading, processing, and storing -// the resulting HRTF. -struct HrirDataT { - uint mIrRate, - mIrCount, - mIrSize, - mIrPoints, - mFftSize, - mEvCount, - mEvStart, - mAzCount [MAX_EV_COUNT], - mEvOffset [MAX_EV_COUNT]; - double mRadius, - mDistance, - * mHrirs, - * mHrtds, - mMaxHrtd; -}; - -// The resampler metrics and FIR filter. -struct ResamplerT { - uint mP, - mQ, - mM, - mL; - double * mF; -}; - -/* Token reader routines for parsing text files. Whitespace is not - * significant. It can process tokens as identifiers, numbers (integer and - * floating-point), strings, and operators. Strings must be encapsulated by - * double-quotes and cannot span multiple lines. - */ - -// Setup the reader on the given file. The filename can be NULL if no error -// output is desired. -static void TrSetup (FILE * fp, const char * filename, TokenReaderT * tr) { - const char * name = NULL; - char ch; - - tr -> mFile = fp; - name = filename; - // If a filename was given, store a pointer to the base name. - if (filename != NULL) { - while ((ch = (* filename)) != '\0') { - if ((ch == '/') || (ch == '\\')) - name = filename + 1; - filename ++; - } - } - tr -> mName = name; - tr -> mLine = 1; - tr -> mColumn = 1; - tr -> mIn = 0; - tr -> mOut = 0; -} - -// Prime the reader's ring buffer, and return a result indicating that there -// is text to process. -static int TrLoad (TokenReaderT * tr) { - size_t toLoad, in, count; - - toLoad = TR_RING_SIZE - (tr -> mIn - tr -> mOut); - if ((toLoad >= TR_LOAD_SIZE) && (! feof (tr -> mFile))) { - // Load TR_LOAD_SIZE (or less if at the end of the file) per read. - toLoad = TR_LOAD_SIZE; - in = tr -> mIn & TR_RING_MASK; - count = TR_RING_SIZE - in; - if (count < toLoad) { - tr -> mIn += fread (& tr -> mRing [in], 1, count, tr -> mFile); - tr -> mIn += fread (& tr -> mRing [0], 1, toLoad - count, tr -> mFile); - } else { - tr -> mIn += fread (& tr -> mRing [in], 1, toLoad, tr -> mFile); - } - if (tr -> mOut >= TR_RING_SIZE) { - tr -> mOut -= TR_RING_SIZE; - tr -> mIn -= TR_RING_SIZE; - } - } - if (tr -> mIn > tr -> mOut) - return (1); - return (0); -} - -// Error display routine. Only displays when the base name is not NULL. -static void TrErrorVA (const TokenReaderT * tr, uint line, uint column, const char * format, va_list argPtr) { - if (tr -> mName != NULL) { - fprintf (stderr, "Error (%s:%u:%u): ", tr -> mName, line, column); - vfprintf (stderr, format, argPtr); - } -} - -// Used to display an error at a saved line/column. -static void TrErrorAt (const TokenReaderT * tr, uint line, uint column, const char * format, ...) { - va_list argPtr; - - va_start (argPtr, format); - TrErrorVA (tr, line, column, format, argPtr); - va_end (argPtr); -} - -// Used to display an error at the current line/column. -static void TrError (const TokenReaderT * tr, const char * format, ...) { - va_list argPtr; - - va_start (argPtr, format); - TrErrorVA (tr, tr -> mLine, tr -> mColumn, format, argPtr); - va_end (argPtr); -} - -// Skips to the next line. -static void TrSkipLine (TokenReaderT * tr) { - char ch; - - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - tr -> mOut ++; - if (ch == '\n') { - tr -> mLine ++; - tr -> mColumn = 1; - break; - } - tr -> mColumn ++; - } -} - -// Skips to the next token. -static int TrSkipWhitespace (TokenReaderT * tr) { - char ch; - - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (isspace (ch)) { - tr -> mOut ++; - if (ch == '\n') { - tr -> mLine ++; - tr -> mColumn = 1; - } else { - tr -> mColumn ++; - } - } else if (ch == '#') { - TrSkipLine (tr); - } else { - return (1); - } - } - return (0); -} - -// Get the line and/or column of the next token (or the end of input). -static void TrIndication (TokenReaderT * tr, uint * line, uint * column) { - TrSkipWhitespace (tr); - if (line != NULL) - (* line) = tr -> mLine; - if (column != NULL) - (* column) = tr -> mColumn; -} - -// Checks to see if a token is the given operator. It does not display any -// errors and will not proceed to the next token. -static int TrIsOperator (TokenReaderT * tr, const char * op) { - size_t out, len; - char ch; - - if (! TrSkipWhitespace (tr)) - return (0); - out = tr -> mOut; - len = 0; - while ((op [len] != '\0') && (out < tr -> mIn)) { - ch = tr -> mRing [out & TR_RING_MASK]; - if (ch != op [len]) - break; - len ++; - out ++; - } - if (op [len] == '\0') - return (1); - return (0); -} - -/* The TrRead*() routines obtain the value of a matching token type. They - * display type, form, and boundary errors and will proceed to the next - * token. - */ - -// Reads and validates an identifier token. -static int TrReadIdent (TokenReaderT * tr, const uint maxLen, char * ident) { - uint col, len; - char ch; - - col = tr -> mColumn; - if (TrSkipWhitespace (tr)) { - col = tr -> mColumn; - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if ((ch == '_') || isalpha (ch)) { - len = 0; - do { - if (len < maxLen) - ident [len] = ch; - len ++; - tr -> mOut ++; - if (! TrLoad (tr)) - break; - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - } while ((ch == '_') || isdigit (ch) || isalpha (ch)); - tr -> mColumn += len; - if (len > maxLen) { - TrErrorAt (tr, tr -> mLine, col, "Identifier is too long.\n"); - return (0); - } - ident [len] = '\0'; - return (1); - } - } - TrErrorAt (tr, tr -> mLine, col, "Expected an identifier.\n"); - return (0); -} - -// Reads and validates (including bounds) an integer token. -static int TrReadInt (TokenReaderT * tr, const int loBound, const int hiBound, int * value) { - uint col, digis, len; - char ch, temp [64 + 1]; - - col = tr -> mColumn; - if (TrSkipWhitespace (tr)) { - col = tr -> mColumn; - len = 0; - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if ((ch == '+') || (ch == '-')) { - temp [len] = ch; - len ++; - tr -> mOut ++; - } - digis = 0; - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (! isdigit (ch)) - break; - if (len < 64) - temp [len] = ch; - len ++; - digis ++; - tr -> mOut ++; - } - tr -> mColumn += len; - if ((digis > 0) && (ch != '.') && (! isalpha (ch))) { - if (len > 64) { - TrErrorAt (tr, tr -> mLine, col, "Integer is too long."); - return (0); - } - temp [len] = '\0'; - (* value) = strtol (temp, NULL, 10); - if (((* value) < loBound) || ((* value) > hiBound)) { - TrErrorAt (tr, tr -> mLine, col, "Expected a value from %d to %d.\n", loBound, hiBound); - return (0); - } - return (1); - } - } - TrErrorAt (tr, tr -> mLine, col, "Expected an integer.\n"); - return (0); -} - -// Reads and validates (including bounds) a float token. -static int TrReadFloat (TokenReaderT * tr, const double loBound, const double hiBound, double * value) { - uint col, digis, len; - char ch, temp [64 + 1]; - - col = tr -> mColumn; - if (TrSkipWhitespace (tr)) { - col = tr -> mColumn; - len = 0; - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if ((ch == '+') || (ch == '-')) { - temp [len] = ch; - len ++; - tr -> mOut ++; - } - digis = 0; - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (! isdigit (ch)) - break; - if (len < 64) - temp [len] = ch; - len ++; - digis ++; - tr -> mOut ++; - } - if (ch == '.') { - if (len < 64) - temp [len] = ch; - len ++; - tr -> mOut ++; - } - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (! isdigit (ch)) - break; - if (len < 64) - temp [len] = ch; - len ++; - digis ++; - tr -> mOut ++; - } - if (digis > 0) { - if ((ch == 'E') || (ch == 'e')) { - if (len < 64) - temp [len] = ch; - len ++; - digis = 0; - tr -> mOut ++; - if ((ch == '+') || (ch == '-')) { - if (len < 64) - temp [len] = ch; - len ++; - tr -> mOut ++; - } - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (! isdigit (ch)) - break; - if (len < 64) - temp [len] = ch; - len ++; - digis ++; - tr -> mOut ++; - } - } - tr -> mColumn += len; - if ((digis > 0) && (ch != '.') && (! isalpha (ch))) { - if (len > 64) { - TrErrorAt (tr, tr -> mLine, col, "Float is too long."); - return (0); - } - temp [len] = '\0'; - (* value) = strtod (temp, NULL); - if (((* value) < loBound) || ((* value) > hiBound)) { - TrErrorAt (tr, tr -> mLine, col, "Expected a value from %f to %f.\n", loBound, hiBound); - return (0); - } - return (1); - } - } else { - tr -> mColumn += len; - } - } - TrErrorAt (tr, tr -> mLine, col, "Expected a float.\n"); - return (0); -} - -// Reads and validates a string token. -static int TrReadString (TokenReaderT * tr, const uint maxLen, char * text) { - uint col, len; - char ch; - - col = tr -> mColumn; - if (TrSkipWhitespace (tr)) { - col = tr -> mColumn; - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (ch == '\"') { - tr -> mOut ++; - len = 0; - while (TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - tr -> mOut ++; - if (ch == '\"') - break; - if (ch == '\n') { - TrErrorAt (tr, tr -> mLine, col, "Unterminated string at end of line.\n"); - return (0); - } - if (len < maxLen) - text [len] = ch; - len ++; - } - if (ch != '\"') { - tr -> mColumn += 1 + len; - TrErrorAt (tr, tr -> mLine, col, "Unterminated string at end of input.\n"); - return (0); - } - tr -> mColumn += 2 + len; - if (len > maxLen) { - TrErrorAt (tr, tr -> mLine, col, "String is too long.\n"); - return (0); - } - text [len] = '\0'; - return (1); - } - } - TrErrorAt (tr, tr -> mLine, col, "Expected a string.\n"); - return (0); -} - -// Reads and validates the given operator. -static int TrReadOperator (TokenReaderT * tr, const char * op) { - uint col, len; - char ch; - - col = tr -> mColumn; - if (TrSkipWhitespace (tr)) { - col = tr -> mColumn; - len = 0; - while ((op [len] != '\0') && TrLoad (tr)) { - ch = tr -> mRing [tr -> mOut & TR_RING_MASK]; - if (ch != op [len]) - break; - len ++; - tr -> mOut ++; - } - tr -> mColumn += len; - if (op [len] == '\0') - return (1); - } - TrErrorAt (tr, tr -> mLine, col, "Expected '%s' operator.\n", op); - return (0); -} - -/* Performs a string substitution. Any case-insensitive occurrences of the - * pattern string are replaced with the replacement string. The result is - * truncated if necessary. - */ -static int StrSubst (const char * in, const char * pat, const char * rep, const size_t maxLen, char * out) { - size_t inLen, patLen, repLen; - size_t si, di; - int truncated; - - inLen = strlen (in); - patLen = strlen (pat); - repLen = strlen (rep); - si = 0; - di = 0; - truncated = 0; - while ((si < inLen) && (di < maxLen)) { - if (patLen <= (inLen - si)) { - if (strncasecmp (& in [si], pat, patLen) == 0) { - if (repLen > (maxLen - di)) { - repLen = maxLen - di; - truncated = 1; - } - strncpy (& out [di], rep, repLen); - si += patLen; - di += repLen; - } - } - out [di] = in [si]; - si ++; - di ++; - } - if (si < inLen) - truncated = 1; - out [di] = '\0'; - return (! truncated); -} - -// Provide missing math routines for MSVC versions < 1800 (Visual Studio 2013). -#if defined(_MSC_VER) && _MSC_VER < 1800 -static double round (double val) { - if (val < 0.0) - return (ceil (val - 0.5)); - return (floor (val + 0.5)); -} - -static double fmin (double a, double b) { - return ((a < b) ? a : b); -} - -static double fmax (double a, double b) { - return ((a > b) ? a : b); -} -#endif - -// Simple clamp routine. -static double Clamp (const double val, const double lower, const double upper) { - return (fmin (fmax (val, lower), upper)); -} - -// Performs linear interpolation. -static double Lerp (const double a, const double b, const double f) { - return (a + (f * (b - a))); -} - -// Performs a high-passed triangular probability density function dither from -// a double to an integer. It assumes the input sample is already scaled. -static int HpTpdfDither (const double in, int * hpHist) { - const double PRNG_SCALE = 1.0 / (RAND_MAX + 1.0); - int prn; - double out; - - prn = rand (); - out = round (in + (PRNG_SCALE * (prn - (* hpHist)))); - (* hpHist) = prn; - return ((int) out); -} - -// Allocates an array of doubles. -static double *CreateArray(size_t n) -{ - double *a; - - if(n == 0) n = 1; - a = calloc(n, sizeof(double)); - if(a == NULL) - { - fprintf(stderr, "Error: Out of memory.\n"); - exit(-1); - } - return a; -} - -// Frees an array of doubles. -static void DestroyArray(double *a) -{ free(a); } - -// Complex number routines. All outputs must be non-NULL. - -// Magnitude/absolute value. -static double ComplexAbs (const double r, const double i) { - return (sqrt ((r * r) + (i * i))); -} - -// Multiply. -static void ComplexMul (const double aR, const double aI, const double bR, const double bI, double * outR, double * outI) { - (* outR) = (aR * bR) - (aI * bI); - (* outI) = (aI * bR) + (aR * bI); -} - -// Base-e exponent. -static void ComplexExp (const double inR, const double inI, double * outR, double * outI) { - double e; - - e = exp (inR); - (* outR) = e * cos (inI); - (* outI) = e * sin (inI); -} - -/* Fast Fourier transform routines. The number of points must be a power of - * two. In-place operation is possible only if both the real and imaginary - * parts are in-place together. - */ - -// Performs bit-reversal ordering. -static void FftArrange (const uint n, const double * inR, const double * inI, double * outR, double * outI) { - uint rk, k, m; - double tempR, tempI; - - if ((inR == outR) && (inI == outI)) { - // Handle in-place arrangement. - rk = 0; - for (k = 0; k < n; k ++) { - if (rk > k) { - tempR = inR [rk]; - tempI = inI [rk]; - outR [rk] = inR [k]; - outI [rk] = inI [k]; - outR [k] = tempR; - outI [k] = tempI; - } - m = n; - while (rk & (m >>= 1)) - rk &= ~m; - rk |= m; - } - } else { - // Handle copy arrangement. - rk = 0; - for (k = 0; k < n; k ++) { - outR [rk] = inR [k]; - outI [rk] = inI [k]; - m = n; - while (rk & (m >>= 1)) - rk &= ~m; - rk |= m; - } - } -} - -// Performs the summation. -static void FftSummation (const uint n, const double s, double * re, double * im) { - double pi; - uint m, m2; - double vR, vI, wR, wI; - uint i, k, mk; - double tR, tI; - - pi = s * M_PI; - for (m = 1, m2 = 2; m < n; m <<= 1, m2 <<= 1) { - // v = Complex (-2.0 * sin (0.5 * pi / m) * sin (0.5 * pi / m), -sin (pi / m)) - vR = sin (0.5 * pi / m); - vR = -2.0 * vR * vR; - vI = -sin (pi / m); - // w = Complex (1.0, 0.0) - wR = 1.0; - wI = 0.0; - for (i = 0; i < m; i ++) { - for (k = i; k < n; k += m2) { - mk = k + m; - // t = ComplexMul (w, out [km2]) - tR = (wR * re [mk]) - (wI * im [mk]); - tI = (wR * im [mk]) + (wI * re [mk]); - // out [mk] = ComplexSub (out [k], t) - re [mk] = re [k] - tR; - im [mk] = im [k] - tI; - // out [k] = ComplexAdd (out [k], t) - re [k] += tR; - im [k] += tI; - } - // t = ComplexMul (v, w) - tR = (vR * wR) - (vI * wI); - tI = (vR * wI) + (vI * wR); - // w = ComplexAdd (w, t) - wR += tR; - wI += tI; - } - } -} - -// Performs a forward FFT. -static void FftForward (const uint n, const double * inR, const double * inI, double * outR, double * outI) { - FftArrange (n, inR, inI, outR, outI); - FftSummation (n, 1.0, outR, outI); -} - -// Performs an inverse FFT. -static void FftInverse (const uint n, const double * inR, const double * inI, double * outR, double * outI) { - double f; - uint i; - - FftArrange (n, inR, inI, outR, outI); - FftSummation (n, -1.0, outR, outI); - f = 1.0 / n; - for (i = 0; i < n; i ++) { - outR [i] *= f; - outI [i] *= f; - } -} - -/* Calculate the complex helical sequence (or discrete-time analytical - * signal) of the given input using the Hilbert transform. Given the - * negative natural logarithm of a signal's magnitude response, the imaginary - * components can be used as the angles for minimum-phase reconstruction. - */ -static void Hilbert (const uint n, const double * in, double * outR, double * outI) { - uint i; - - if (in == outR) { - // Handle in-place operation. - for (i = 0; i < n; i ++) - outI [i] = 0.0; - } else { - // Handle copy operation. - for (i = 0; i < n; i ++) { - outR [i] = in [i]; - outI [i] = 0.0; - } - } - FftForward (n, outR, outI, outR, outI); - /* Currently the Fourier routines operate only on point counts that are - * powers of two. If that changes and n is odd, the following conditional - * should be: i < (n + 1) / 2. - */ - for (i = 1; i < (n / 2); i ++) { - outR [i] *= 2.0; - outI [i] *= 2.0; - } - // If n is odd, the following increment should be skipped. - i ++; - for (; i < n; i ++) { - outR [i] = 0.0; - outI [i] = 0.0; - } - FftInverse (n, outR, outI, outR, outI); -} - -/* Calculate the magnitude response of the given input. This is used in - * place of phase decomposition, since the phase residuals are discarded for - * minimum phase reconstruction. The mirrored half of the response is also - * discarded. - */ -static void MagnitudeResponse (const uint n, const double * inR, const double * inI, double * out) { - const uint m = 1 + (n / 2); - uint i; - - for (i = 0; i < m; i ++) - out [i] = fmax (ComplexAbs (inR [i], inI [i]), EPSILON); -} - -/* Apply a range limit (in dB) to the given magnitude response. This is used - * to adjust the effects of the diffuse-field average on the equalization - * process. - */ -static void LimitMagnitudeResponse (const uint n, const double limit, const double * in, double * out) { - const uint m = 1 + (n / 2); - double halfLim; - uint i, lower, upper; - double ave; - - halfLim = limit / 2.0; - // Convert the response to dB. - for (i = 0; i < m; i ++) - out [i] = 20.0 * log10 (in [i]); - // Use six octaves to calculate the average magnitude of the signal. - lower = ((uint) ceil (n / pow (2.0, 8.0))) - 1; - upper = ((uint) floor (n / pow (2.0, 2.0))) - 1; - ave = 0.0; - for (i = lower; i <= upper; i ++) - ave += out [i]; - ave /= upper - lower + 1; - // Keep the response within range of the average magnitude. - for (i = 0; i < m; i ++) - out [i] = Clamp (out [i], ave - halfLim, ave + halfLim); - // Convert the response back to linear magnitude. - for (i = 0; i < m; i ++) - out [i] = pow (10.0, out [i] / 20.0); -} - -/* Reconstructs the minimum-phase component for the given magnitude response - * of a signal. This is equivalent to phase recomposition, sans the missing - * residuals (which were discarded). The mirrored half of the response is - * reconstructed. - */ -static void MinimumPhase (const uint n, const double * in, double * outR, double * outI) { - const uint m = 1 + (n / 2); - double * mags = NULL; - uint i; - double aR, aI; - - mags = CreateArray (n); - for (i = 0; i < m; i ++) { - mags [i] = fmax (in [i], EPSILON); - outR [i] = -log (mags [i]); - } - for (; i < n; i ++) { - mags [i] = mags [n - i]; - outR [i] = outR [n - i]; - } - Hilbert (n, outR, outR, outI); - // Remove any DC offset the filter has. - outR [0] = 0.0; - outI [0] = 0.0; - for (i = 1; i < n; i ++) { - ComplexExp (0.0, outI [i], & aR, & aI); - ComplexMul (mags [i], 0.0, aR, aI, & outR [i], & outI [i]); - } - DestroyArray (mags); -} - -/* This is the normalized cardinal sine (sinc) function. - * - * sinc(x) = { 1, x = 0 - * { sin(pi x) / (pi x), otherwise. - */ -static double Sinc (const double x) { - if (fabs (x) < EPSILON) - return (1.0); - return (sin (M_PI * x) / (M_PI * x)); -} - -/* The zero-order modified Bessel function of the first kind, used for the - * Kaiser window. - * - * I_0(x) = sum_{k=0}^inf (1 / k!)^2 (x / 2)^(2 k) - * = sum_{k=0}^inf ((x / 2)^k / k!)^2 - */ -static double BesselI_0 (const double x) { - double term, sum, x2, y, last_sum; - int k; - - // Start at k=1 since k=0 is trivial. - term = 1.0; - sum = 1.0; - x2 = x / 2.0; - k = 1; - // Let the integration converge until the term of the sum is no longer - // significant. - do { - y = x2 / k; - k ++; - last_sum = sum; - term *= y * y; - sum += term; - } while (sum != last_sum); - return (sum); -} - -/* Calculate a Kaiser window from the given beta value and a normalized k - * [-1, 1]. - * - * w(k) = { I_0(B sqrt(1 - k^2)) / I_0(B), -1 <= k <= 1 - * { 0, elsewhere. - * - * Where k can be calculated as: - * - * k = i / l, where -l <= i <= l. - * - * or: - * - * k = 2 i / M - 1, where 0 <= i <= M. - */ -static double Kaiser (const double b, const double k) { - double k2; - - k2 = Clamp (k, -1.0, 1.0); - if ((k < -1.0) || (k > 1.0)) - return (0.0); - k2 *= k2; - return (BesselI_0 (b * sqrt (1.0 - k2)) / BesselI_0 (b)); -} - -// Calculates the greatest common divisor of a and b. -static uint Gcd (const uint a, const uint b) { - uint x, y, z; - - x = a; - y = b; - while (y > 0) { - z = y; - y = x % y; - x = z; - } - return (x); -} - -/* Calculates the size (order) of the Kaiser window. Rejection is in dB and - * the transition width is normalized frequency (0.5 is nyquist). - * - * M = { ceil((r - 7.95) / (2.285 2 pi f_t)), r > 21 - * { ceil(5.79 / 2 pi f_t), r <= 21. - * - */ -static uint CalcKaiserOrder (const double rejection, const double transition) { - double w_t; - - w_t = 2.0 * M_PI * transition; - if (rejection > 21.0) - return ((uint) ceil ((rejection - 7.95) / (2.285 * w_t))); - return ((uint) ceil (5.79 / w_t)); -} - -// Calculates the beta value of the Kaiser window. Rejection is in dB. -static double CalcKaiserBeta (const double rejection) { - if (rejection > 50.0) - return (0.1102 * (rejection - 8.7)); - else if (rejection >= 21.0) - return ((0.5842 * pow (rejection - 21.0, 0.4)) + - (0.07886 * (rejection - 21.0))); - else - return (0.0); -} - -/* Calculates a point on the Kaiser-windowed sinc filter for the given half- - * width, beta, gain, and cutoff. The point is specified in non-normalized - * samples, from 0 to M, where M = (2 l + 1). - * - * w(k) 2 p f_t sinc(2 f_t x) - * - * x -- centered sample index (i - l) - * k -- normalized and centered window index (x / l) - * w(k) -- window function (Kaiser) - * p -- gain compensation factor when sampling - * f_t -- normalized center frequency (or cutoff; 0.5 is nyquist) - */ -static double SincFilter (const int l, const double b, const double gain, const double cutoff, const int i) { - return (Kaiser (b, ((double) (i - l)) / l) * 2.0 * gain * cutoff * Sinc (2.0 * cutoff * (i - l))); -} - -/* This is a polyphase sinc-filtered resampler. - * - * Upsample Downsample - * - * p/q = 3/2 p/q = 3/5 - * - * M-+-+-+-> M-+-+-+-> - * -------------------+ ---------------------+ - * p s * f f f f|f| | p s * f f f f f | - * | 0 * 0 0 0|0|0 | | 0 * 0 0 0 0|0| | - * v 0 * 0 0|0|0 0 | v 0 * 0 0 0|0|0 | - * s * f|f|f f f | s * f f|f|f f | - * 0 * |0|0 0 0 0 | 0 * 0|0|0 0 0 | - * --------+=+--------+ 0 * |0|0 0 0 0 | - * d . d .|d|. d . d ----------+=+--------+ - * d . . . .|d|. . . . - * q-> - * q-+-+-+-> - * - * P_f(i,j) = q i mod p + pj - * P_s(i,j) = floor(q i / p) - j - * d[i=0..N-1] = sum_{j=0}^{floor((M - 1) / p)} { - * { f[P_f(i,j)] s[P_s(i,j)], P_f(i,j) < M - * { 0, P_f(i,j) >= M. } - */ - -// Calculate the resampling metrics and build the Kaiser-windowed sinc filter -// that's used to cut frequencies above the destination nyquist. -static void ResamplerSetup (ResamplerT * rs, const uint srcRate, const uint dstRate) { - uint gcd, l; - double cutoff, width, beta; - int i; - - gcd = Gcd (srcRate, dstRate); - rs -> mP = dstRate / gcd; - rs -> mQ = srcRate / gcd; - /* The cutoff is adjusted by half the transition width, so the transition - * ends before the nyquist (0.5). Both are scaled by the downsampling - * factor. - */ - if (rs -> mP > rs -> mQ) { - cutoff = 0.45 / rs -> mP; - width = 0.1 / rs -> mP; - } else { - cutoff = 0.45 / rs -> mQ; - width = 0.1 / rs -> mQ; - } - // A rejection of -180 dB is used for the stop band. - l = CalcKaiserOrder (180.0, width) / 2; - beta = CalcKaiserBeta (180.0); - rs -> mM = (2 * l) + 1; - rs -> mL = l; - rs -> mF = CreateArray (rs -> mM); - for (i = 0; i < ((int) rs -> mM); i ++) - rs -> mF [i] = SincFilter ((int) l, beta, rs -> mP, cutoff, i); -} - -// Clean up after the resampler. -static void ResamplerClear (ResamplerT * rs) { - DestroyArray (rs -> mF); - rs -> mF = NULL; -} - -// Perform the upsample-filter-downsample resampling operation using a -// polyphase filter implementation. -static void ResamplerRun (ResamplerT * rs, const uint inN, const double * in, const uint outN, double * out) { - const uint p = rs -> mP, q = rs -> mQ, m = rs -> mM, l = rs -> mL; - const double * f = rs -> mF; - double * work = NULL; - uint i; - double r; - uint j_f, j_s; - - if (outN == 0) - return; - - // Handle in-place operation. - if (in == out) - work = CreateArray (outN); - else - work = out; - // Resample the input. - for (i = 0; i < outN; i ++) { - r = 0.0; - // Input starts at l to compensate for the filter delay. This will - // drop any build-up from the first half of the filter. - j_f = (l + (q * i)) % p; - j_s = (l + (q * i)) / p; - while (j_f < m) { - // Only take input when 0 <= j_s < inN. This single unsigned - // comparison catches both cases. - if (j_s < inN) - r += f [j_f] * in [j_s]; - j_f += p; - j_s --; - } - work [i] = r; - } - // Clean up after in-place operation. - if (in == out) { - for (i = 0; i < outN; i ++) - out [i] = work [i]; - DestroyArray (work); - } -} - -// Read a binary value of the specified byte order and byte size from a file, -// storing it as a 32-bit unsigned integer. -static int ReadBin4 (FILE * fp, const char * filename, const ByteOrderT order, const uint bytes, uint32 * out) { - uint8 in [4]; - uint32 accum; - uint i; - - if (fread (in, 1, bytes, fp) != bytes) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); - return (0); - } - accum = 0; - switch (order) { - case BO_LITTLE : - for (i = 0; i < bytes; i ++) - accum = (accum << 8) | in [bytes - i - 1]; - break; - case BO_BIG : - for (i = 0; i < bytes; i ++) - accum = (accum << 8) | in [i]; - break; - default : - break; - } - (* out) = accum; - return (1); -} - -// Read a binary value of the specified byte order from a file, storing it as -// a 64-bit unsigned integer. -static int ReadBin8 (FILE * fp, const char * filename, const ByteOrderT order, uint64 * out) { - uint8 in [8]; - uint64 accum; - uint i; - - if (fread (in, 1, 8, fp) != 8) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); - return (0); - } - accum = 0ULL; - switch (order) { - case BO_LITTLE : - for (i = 0; i < 8; i ++) - accum = (accum << 8) | in [8 - i - 1]; - break; - case BO_BIG : - for (i = 0; i < 8; i ++) - accum = (accum << 8) | in [i]; - break; - default : - break; - } - (* out) = accum; - return (1); -} - -// Write an ASCII string to a file. -static int WriteAscii (const char * out, FILE * fp, const char * filename) { - size_t len; - - len = strlen (out); - if (fwrite (out, 1, len, fp) != len) { - fclose (fp); - fprintf (stderr, "Error: Bad write to file '%s'.\n", filename); - return (0); - } - return (1); -} - -// Write a binary value of the given byte order and byte size to a file, -// loading it from a 32-bit unsigned integer. -static int WriteBin4 (const ByteOrderT order, const uint bytes, const uint32 in, FILE * fp, const char * filename) { - uint8 out [4]; - uint i; - - switch (order) { - case BO_LITTLE : - for (i = 0; i < bytes; i ++) - out [i] = (in >> (i * 8)) & 0x000000FF; - break; - case BO_BIG : - for (i = 0; i < bytes; i ++) - out [bytes - i - 1] = (in >> (i * 8)) & 0x000000FF; - break; - default : - break; - } - if (fwrite (out, 1, bytes, fp) != bytes) { - fprintf (stderr, "Error: Bad write to file '%s'.\n", filename); - return (0); - } - return (1); -} - -/* Read a binary value of the specified type, byte order, and byte size from - * a file, converting it to a double. For integer types, the significant - * bits are used to normalize the result. The sign of bits determines - * whether they are padded toward the MSB (negative) or LSB (positive). - * Floating-point types are not normalized. - */ -static int ReadBinAsDouble (FILE * fp, const char * filename, const ByteOrderT order, const ElementTypeT type, const uint bytes, const int bits, double * out) { - union { - uint32 ui; - int32 i; - float f; - } v4; - union { - uint64 ui; - double f; - } v8; - - (* out) = 0.0; - if (bytes > 4) { - if (! ReadBin8 (fp, filename, order, & v8 . ui)) - return (0); - if (type == ET_FP) - (* out) = v8 . f; - } else { - if (! ReadBin4 (fp, filename, order, bytes, & v4 . ui)) - return (0); - if (type == ET_FP) { - (* out) = (double) v4 . f; - } else { - if (bits > 0) - v4 . ui >>= (8 * bytes) - ((uint) bits); - else - v4 . ui &= (0xFFFFFFFF >> (32 + bits)); - if (v4 . ui & ((uint) (1 << (abs (bits) - 1)))) - v4 . ui |= (0xFFFFFFFF << abs (bits)); - (* out) = v4 . i / ((double) (1 << (abs (bits) - 1))); - } - } - return (1); -} - -/* Read an ascii value of the specified type from a file, converting it to a - * double. For integer types, the significant bits are used to normalize the - * result. The sign of the bits should always be positive. This also skips - * up to one separator character before the element itself. - */ -static int ReadAsciiAsDouble (TokenReaderT * tr, const char * filename, const ElementTypeT type, const uint bits, double * out) { - int v; - - if (TrIsOperator (tr, ",")) - TrReadOperator (tr, ","); - else if (TrIsOperator (tr, ":")) - TrReadOperator (tr, ":"); - else if (TrIsOperator (tr, ";")) - TrReadOperator (tr, ";"); - else if (TrIsOperator (tr, "|")) - TrReadOperator (tr, "|"); - if (type == ET_FP) { - if (! TrReadFloat (tr, -HUGE_VAL, HUGE_VAL, out)) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); - return (0); - } - } else { - if (! TrReadInt (tr, -(1 << (bits - 1)), (1 << (bits - 1)) - 1, & v)) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", filename); - return (0); - } - (* out) = v / ((double) ((1 << (bits - 1)) - 1)); - } - return (1); -} - -// Read the RIFF/RIFX WAVE format chunk from a file, validating it against -// the source parameters and data set metrics. -static int ReadWaveFormat (FILE * fp, const ByteOrderT order, const uint hrirRate, SourceRefT * src) { - uint32 fourCC, chunkSize; - uint32 format, channels, rate, dummy, block, size, bits; - - chunkSize = 0; - do { - if (chunkSize > 0) - fseek (fp, (long) chunkSize, SEEK_CUR); - if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || - (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) - return (0); - } while (fourCC != FOURCC_FMT); - if ((! ReadBin4 (fp, src -> mPath, order, 2, & format)) || - (! ReadBin4 (fp, src -> mPath, order, 2, & channels)) || - (! ReadBin4 (fp, src -> mPath, order, 4, & rate)) || - (! ReadBin4 (fp, src -> mPath, order, 4, & dummy)) || - (! ReadBin4 (fp, src -> mPath, order, 2, & block))) - return (0); - block /= channels; - if (chunkSize > 14) { - if (! ReadBin4 (fp, src -> mPath, order, 2, & size)) - return (0); - size /= 8; - if (block > size) - size = block; - } else { - size = block; - } - if (format == WAVE_FORMAT_EXTENSIBLE) { - fseek (fp, 2, SEEK_CUR); - if (! ReadBin4 (fp, src -> mPath, order, 2, & bits)) - return (0); - if (bits == 0) - bits = 8 * size; - fseek (fp, 4, SEEK_CUR); - if (! ReadBin4 (fp, src -> mPath, order, 2, & format)) - return (0); - fseek (fp, (long) (chunkSize - 26), SEEK_CUR); - } else { - bits = 8 * size; - if (chunkSize > 14) - fseek (fp, (long) (chunkSize - 16), SEEK_CUR); - else - fseek (fp, (long) (chunkSize - 14), SEEK_CUR); - } - if ((format != WAVE_FORMAT_PCM) && (format != WAVE_FORMAT_IEEE_FLOAT)) { - fprintf (stderr, "Error: Unsupported WAVE format in file '%s'.\n", src -> mPath); - return (0); - } - if (src -> mChannel >= channels) { - fprintf (stderr, "Error: Missing source channel in WAVE file '%s'.\n", src -> mPath); - return (0); - } - if (rate != hrirRate) { - fprintf (stderr, "Error: Mismatched source sample rate in WAVE file '%s'.\n", src -> mPath); - return (0); - } - if (format == WAVE_FORMAT_PCM) { - if ((size < 2) || (size > 4)) { - fprintf (stderr, "Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath); - return (0); - } - if ((bits < 16) || (bits > (8 * size))) { - fprintf (stderr, "Error: Bad significant bits in WAVE file '%s'.\n", src -> mPath); - return (0); - } - src -> mType = ET_INT; - } else { - if ((size != 4) && (size != 8)) { - fprintf (stderr, "Error: Unsupported sample size in WAVE file '%s'.\n", src -> mPath); - return (0); - } - src -> mType = ET_FP; - } - src -> mSize = size; - src -> mBits = (int) bits; - src -> mSkip = channels; - return (1); -} - -// Read a RIFF/RIFX WAVE data chunk, converting all elements to doubles. -static int ReadWaveData (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { - int pre, post, skip; - uint i; - - pre = (int) (src -> mSize * src -> mChannel); - post = (int) (src -> mSize * (src -> mSkip - src -> mChannel - 1)); - skip = 0; - for (i = 0; i < n; i ++) { - skip += pre; - if (skip > 0) - fseek (fp, skip, SEEK_CUR); - if (! ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i])) - return (0); - skip = post; - } - if (skip > 0) - fseek (fp, skip, SEEK_CUR); - return (1); -} - -// Read the RIFF/RIFX WAVE list or data chunk, converting all elements to -// doubles. -static int ReadWaveList (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { - uint32 fourCC, chunkSize, listSize, count; - uint block, skip, offset, i; - double lastSample; - - for (;;) { - if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || - (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) - return (0); - if (fourCC == FOURCC_DATA) { - block = src -> mSize * src -> mSkip; - count = chunkSize / block; - if (count < (src -> mOffset + n)) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", src -> mPath); - return (0); - } - fseek (fp, (long) (src -> mOffset * block), SEEK_CUR); - if (! ReadWaveData (fp, src, order, n, & hrir [0])) - return (0); - return (1); - } else if (fourCC == FOURCC_LIST) { - if (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) - return (0); - chunkSize -= 4; - if (fourCC == FOURCC_WAVL) - break; - } - if (chunkSize > 0) - fseek (fp, (long) chunkSize, SEEK_CUR); - } - listSize = chunkSize; - block = src -> mSize * src -> mSkip; - skip = src -> mOffset; - offset = 0; - lastSample = 0.0; - while ((offset < n) && (listSize > 8)) { - if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || - (! ReadBin4 (fp, src -> mPath, order, 4, & chunkSize))) - return (0); - listSize -= 8 + chunkSize; - if (fourCC == FOURCC_DATA) { - count = chunkSize / block; - if (count > skip) { - fseek (fp, (long) (skip * block), SEEK_CUR); - chunkSize -= skip * block; - count -= skip; - skip = 0; - if (count > (n - offset)) - count = n - offset; - if (! ReadWaveData (fp, src, order, count, & hrir [offset])) - return (0); - chunkSize -= count * block; - offset += count; - lastSample = hrir [offset - 1]; - } else { - skip -= count; - count = 0; - } - } else if (fourCC == FOURCC_SLNT) { - if (! ReadBin4 (fp, src -> mPath, order, 4, & count)) - return (0); - chunkSize -= 4; - if (count > skip) { - count -= skip; - skip = 0; - if (count > (n - offset)) - count = n - offset; - for (i = 0; i < count; i ++) - hrir [offset + i] = lastSample; - offset += count; - } else { - skip -= count; - count = 0; - } - } - if (chunkSize > 0) - fseek (fp, (long) chunkSize, SEEK_CUR); - } - if (offset < n) { - fprintf (stderr, "Error: Bad read from file '%s'.\n", src -> mPath); - return (0); - } - return (1); -} - -// Load a source HRIR from a RIFF/RIFX WAVE file. -static int LoadWaveSource (FILE * fp, SourceRefT * src, const uint hrirRate, const uint n, double * hrir) { - uint32 fourCC, dummy; - ByteOrderT order; - - if ((! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) || - (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & dummy))) - return (0); - if (fourCC == FOURCC_RIFF) { - order = BO_LITTLE; - } else if (fourCC == FOURCC_RIFX) { - order = BO_BIG; - } else { - fprintf (stderr, "Error: No RIFF/RIFX chunk in file '%s'.\n", src -> mPath); - return (0); - } - if (! ReadBin4 (fp, src -> mPath, BO_LITTLE, 4, & fourCC)) - return (0); - if (fourCC != FOURCC_WAVE) { - fprintf (stderr, "Error: Not a RIFF/RIFX WAVE file '%s'.\n", src -> mPath); - return (0); - } - if (! ReadWaveFormat (fp, order, hrirRate, src)) - return (0); - if (! ReadWaveList (fp, src, order, n, hrir)) - return (0); - return (1); -} - -// Load a source HRIR from a binary file. -static int LoadBinarySource (FILE * fp, const SourceRefT * src, const ByteOrderT order, const uint n, double * hrir) { - uint i; - - fseek (fp, (long) src -> mOffset, SEEK_SET); - for (i = 0; i < n; i ++) { - if (! ReadBinAsDouble (fp, src -> mPath, order, src -> mType, src -> mSize, src -> mBits, & hrir [i])) - return (0); - if (src -> mSkip > 0) - fseek (fp, (long) src -> mSkip, SEEK_CUR); - } - return (1); -} - -// Load a source HRIR from an ASCII text file containing a list of elements -// separated by whitespace or common list operators (',', ';', ':', '|'). -static int LoadAsciiSource (FILE * fp, const SourceRefT * src, const uint n, double * hrir) { - TokenReaderT tr; - uint i, j; - double dummy; - - TrSetup (fp, NULL, & tr); - for (i = 0; i < src -> mOffset; i ++) { - if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & dummy)) - return (0); - } - for (i = 0; i < n; i ++) { - if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & hrir [i])) - return (0); - for (j = 0; j < src -> mSkip; j ++) { - if (! ReadAsciiAsDouble (& tr, src -> mPath, src -> mType, (uint) src -> mBits, & dummy)) - return (0); - } - } - return (1); -} - -// Load a source HRIR from a supported file type. -static int LoadSource (SourceRefT * src, const uint hrirRate, const uint n, double * hrir) { - FILE * fp = NULL; - int result; - - if (src -> mFormat == SF_ASCII) - fp = fopen (src -> mPath, "r"); - else - fp = fopen (src -> mPath, "rb"); - if (fp == NULL) { - fprintf (stderr, "Error: Could not open source file '%s'.\n", src -> mPath); - return (0); - } - if (src -> mFormat == SF_WAVE) - result = LoadWaveSource (fp, src, hrirRate, n, hrir); - else if (src -> mFormat == SF_BIN_LE) - result = LoadBinarySource (fp, src, BO_LITTLE, n, hrir); - else if (src -> mFormat == SF_BIN_BE) - result = LoadBinarySource (fp, src, BO_BIG, n, hrir); - else - result = LoadAsciiSource (fp, src, n, hrir); - fclose (fp); - return (result); -} - -// Calculate the onset time of an HRIR and average it with any existing -// timing for its elevation and azimuth. -static void AverageHrirOnset (const double * hrir, const double f, const uint ei, const uint ai, const HrirDataT * hData) { - double mag; - uint n, i, j; - - mag = 0.0; - n = hData -> mIrPoints; - for (i = 0; i < n; i ++) - mag = fmax (fabs (hrir [i]), mag); - mag *= 0.15; - for (i = 0; i < n; i ++) { - if (fabs (hrir [i]) >= mag) - break; - } - j = hData -> mEvOffset [ei] + ai; - hData -> mHrtds [j] = Lerp (hData -> mHrtds [j], ((double) i) / hData -> mIrRate, f); -} - -// Calculate the magnitude response of an HRIR and average it with any -// existing responses for its elevation and azimuth. -static void AverageHrirMagnitude (const double * hrir, const double f, const uint ei, const uint ai, const HrirDataT * hData) { - double * re = NULL, * im = NULL; - uint n, m, i, j; - - n = hData -> mFftSize; - re = CreateArray (n); - im = CreateArray (n); - for (i = 0; i < hData -> mIrPoints; i ++) { - re [i] = hrir [i]; - im [i] = 0.0; - } - for (; i < n; i ++) { - re [i] = 0.0; - im [i] = 0.0; - } - FftForward (n, re, im, re, im); - MagnitudeResponse (n, re, im, re); - m = 1 + (n / 2); - j = (hData -> mEvOffset [ei] + ai) * hData -> mIrSize; - for (i = 0; i < m; i ++) - hData -> mHrirs [j + i] = Lerp (hData -> mHrirs [j + i], re [i], f); - DestroyArray (im); - DestroyArray (re); -} - -/* Calculate the contribution of each HRIR to the diffuse-field average based - * on the area of its surface patch. All patches are centered at the HRIR - * coordinates on the unit sphere and are measured by solid angle. - */ -static void CalculateDfWeights (const HrirDataT * hData, double * weights) { - uint ei; - double evs, sum, ev, up_ev, down_ev, solidAngle; - - evs = 90.0 / (hData -> mEvCount - 1); - sum = 0.0; - for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) { - // For each elevation, calculate the upper and lower limits of the - // patch band. - ev = -90.0 + (ei * 2.0 * evs); - if (ei < (hData -> mEvCount - 1)) - up_ev = (ev + evs) * M_PI / 180.0; - else - up_ev = M_PI / 2.0; - if (ei > 0) - down_ev = (ev - evs) * M_PI / 180.0; - else - down_ev = -M_PI / 2.0; - // Calculate the area of the patch band. - solidAngle = 2.0 * M_PI * (sin (up_ev) - sin (down_ev)); - // Each weight is the area of one patch. - weights [ei] = solidAngle / hData -> mAzCount [ei]; - // Sum the total surface area covered by the HRIRs. - sum += solidAngle; - } - // Normalize the weights given the total surface coverage. - for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) - weights [ei] /= sum; -} - -/* Calculate the diffuse-field average from the given magnitude responses of - * the HRIR set. Weighting can be applied to compensate for the varying - * surface area covered by each HRIR. The final average can then be limited - * by the specified magnitude range (in positive dB; 0.0 to skip). - */ -static void CalculateDiffuseFieldAverage (const HrirDataT * hData, const int weighted, const double limit, double * dfa) { - double * weights = NULL; - uint ei, ai, count, step, start, end, m, j, i; - double weight; - - weights = CreateArray (hData -> mEvCount); - if (weighted) { - // Use coverage weighting to calculate the average. - CalculateDfWeights (hData, weights); - } else { - // If coverage weighting is not used, the weights still need to be - // averaged by the number of HRIRs. - count = 0; - for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) - count += hData -> mAzCount [ei]; - for (ei = hData -> mEvStart; ei < hData -> mEvCount; ei ++) - weights [ei] = 1.0 / count; - } - ei = hData -> mEvStart; - ai = 0; - step = hData -> mIrSize; - start = hData -> mEvOffset [ei] * step; - end = hData -> mIrCount * step; - m = 1 + (hData -> mFftSize / 2); - for (i = 0; i < m; i ++) - dfa [i] = 0.0; - for (j = start; j < end; j += step) { - // Get the weight for this HRIR's contribution. - weight = weights [ei]; - // Add this HRIR's weighted power average to the total. - for (i = 0; i < m; i ++) - dfa [i] += weight * hData -> mHrirs [j + i] * hData -> mHrirs [j + i]; - // Determine the next weight to use. - ai ++; - if (ai >= hData -> mAzCount [ei]) { - ei ++; - ai = 0; - } - } - // Finish the average calculation and keep it from being too small. - for (i = 0; i < m; i ++) - dfa [i] = fmax (sqrt (dfa [i]), EPSILON); - // Apply a limit to the magnitude range of the diffuse-field average if - // desired. - if (limit > 0.0) - LimitMagnitudeResponse (hData -> mFftSize, limit, dfa, dfa); - DestroyArray (weights); -} - -// Perform diffuse-field equalization on the magnitude responses of the HRIR -// set using the given average response. -static void DiffuseFieldEqualize (const double * dfa, const HrirDataT * hData) { - uint step, start, end, m, j, i; - - step = hData -> mIrSize; - start = hData -> mEvOffset [hData -> mEvStart] * step; - end = hData -> mIrCount * step; - m = 1 + (hData -> mFftSize / 2); - for (j = start; j < end; j += step) { - for (i = 0; i < m; i ++) - hData -> mHrirs [j + i] /= dfa [i]; - } -} - -// Perform minimum-phase reconstruction using the magnitude responses of the -// HRIR set. -static void ReconstructHrirs (const HrirDataT * hData) { - double * re = NULL, * im = NULL; - uint step, start, end, n, j, i; - - step = hData -> mIrSize; - start = hData -> mEvOffset [hData -> mEvStart] * step; - end = hData -> mIrCount * step; - n = hData -> mFftSize; - re = CreateArray (n); - im = CreateArray (n); - for (j = start; j < end; j += step) { - MinimumPhase (n, & hData -> mHrirs [j], re, im); - FftInverse (n, re, im, re, im); - for (i = 0; i < hData -> mIrPoints; i ++) - hData -> mHrirs [j + i] = re [i]; - } - DestroyArray (im); - DestroyArray (re); -} - -// Resamples the HRIRs for use at the given sampling rate. -static void ResampleHrirs (const uint rate, HrirDataT * hData) { - ResamplerT rs; - uint n, step, start, end, j; - - ResamplerSetup (& rs, hData -> mIrRate, rate); - n = hData -> mIrPoints; - step = hData -> mIrSize; - start = hData -> mEvOffset [hData -> mEvStart] * step; - end = hData -> mIrCount * step; - for (j = start; j < end; j += step) - ResamplerRun (& rs, n, & hData -> mHrirs [j], n, & hData -> mHrirs [j]); - ResamplerClear (& rs); - hData -> mIrRate = rate; -} - -/* Given an elevation index and an azimuth, calculate the indices of the two - * HRIRs that bound the coordinate along with a factor for calculating the - * continous HRIR using interpolation. - */ -static void CalcAzIndices (const HrirDataT * hData, const uint ei, const double az, uint * j0, uint * j1, double * jf) { - double af; - uint ai; - - af = ((2.0 * M_PI) + az) * hData -> mAzCount [ei] / (2.0 * M_PI); - ai = ((uint) af) % hData -> mAzCount [ei]; - af -= floor (af); - (* j0) = hData -> mEvOffset [ei] + ai; - (* j1) = hData -> mEvOffset [ei] + ((ai + 1) % hData -> mAzCount [ei]); - (* jf) = af; -} - -// Synthesize any missing onset timings at the bottom elevations. This just -// blends between slightly exaggerated known onsets. Not an accurate model. -static void SynthesizeOnsets (HrirDataT * hData) { - uint oi, e, a, j0, j1; - double t, of, jf; - - oi = hData -> mEvStart; - t = 0.0; - for (a = 0; a < hData -> mAzCount [oi]; a ++) - t += hData -> mHrtds [hData -> mEvOffset [oi] + a]; - hData -> mHrtds [0] = 1.32e-4 + (t / hData -> mAzCount [oi]); - for (e = 1; e < hData -> mEvStart; e ++) { - of = ((double) e) / hData -> mEvStart; - for (a = 0; a < hData -> mAzCount [e]; a ++) { - CalcAzIndices (hData, oi, a * 2.0 * M_PI / hData -> mAzCount [e], & j0, & j1, & jf); - hData -> mHrtds [hData -> mEvOffset [e] + a] = Lerp (hData -> mHrtds [0], Lerp (hData -> mHrtds [j0], hData -> mHrtds [j1], jf), of); - } - } -} - -/* Attempt to synthesize any missing HRIRs at the bottom elevations. Right - * now this just blends the lowest elevation HRIRs together and applies some - * attenuation and high frequency damping. It is a simple, if inaccurate - * model. - */ -static void SynthesizeHrirs (HrirDataT * hData) { - uint oi, a, e, step, n, i, j; - double of, b; - uint j0, j1; - double jf; - double lp [4], s0, s1; - - if (hData -> mEvStart <= 0) - return; - step = hData -> mIrSize; - oi = hData -> mEvStart; - n = hData -> mIrPoints; - for (i = 0; i < n; i ++) - hData -> mHrirs [i] = 0.0; - for (a = 0; a < hData -> mAzCount [oi]; a ++) { - j = (hData -> mEvOffset [oi] + a) * step; - for (i = 0; i < n; i ++) - hData -> mHrirs [i] += hData -> mHrirs [j + i] / hData -> mAzCount [oi]; - } - for (e = 1; e < hData -> mEvStart; e ++) { - of = ((double) e) / hData -> mEvStart; - b = (1.0 - of) * (3.5e-6 * hData -> mIrRate); - for (a = 0; a < hData -> mAzCount [e]; a ++) { - j = (hData -> mEvOffset [e] + a) * step; - CalcAzIndices (hData, oi, a * 2.0 * M_PI / hData -> mAzCount [e], & j0, & j1, & jf); - j0 *= step; - j1 *= step; - lp [0] = 0.0; - lp [1] = 0.0; - lp [2] = 0.0; - lp [3] = 0.0; - for (i = 0; i < n; i ++) { - s0 = hData -> mHrirs [i]; - s1 = Lerp (hData -> mHrirs [j0 + i], hData -> mHrirs [j1 + i], jf); - s0 = Lerp (s0, s1, of); - lp [0] = Lerp (s0, lp [0], b); - lp [1] = Lerp (lp [0], lp [1], b); - lp [2] = Lerp (lp [1], lp [2], b); - lp [3] = Lerp (lp [2], lp [3], b); - hData -> mHrirs [j + i] = lp [3]; - } - } - } - b = 3.5e-6 * hData -> mIrRate; - lp [0] = 0.0; - lp [1] = 0.0; - lp [2] = 0.0; - lp [3] = 0.0; - for (i = 0; i < n; i ++) { - s0 = hData -> mHrirs [i]; - lp [0] = Lerp (s0, lp [0], b); - lp [1] = Lerp (lp [0], lp [1], b); - lp [2] = Lerp (lp [1], lp [2], b); - lp [3] = Lerp (lp [2], lp [3], b); - hData -> mHrirs [i] = lp [3]; - } - hData -> mEvStart = 0; -} - -// The following routines assume a full set of HRIRs for all elevations. - -// Normalize the HRIR set and slightly attenuate the result. -static void NormalizeHrirs (const HrirDataT * hData) { - uint step, end, n, j, i; - double maxLevel; - - step = hData -> mIrSize; - end = hData -> mIrCount * step; - n = hData -> mIrPoints; - maxLevel = 0.0; - for (j = 0; j < end; j += step) { - for (i = 0; i < n; i ++) - maxLevel = fmax (fabs (hData -> mHrirs [j + i]), maxLevel); - } - maxLevel = 1.01 * maxLevel; - for (j = 0; j < end; j += step) { - for (i = 0; i < n; i ++) - hData -> mHrirs [j + i] /= maxLevel; - } -} - -// Calculate the left-ear time delay using a spherical head model. -static double CalcLTD (const double ev, const double az, const double rad, const double dist) { - double azp, dlp, l, al; - - azp = asin (cos (ev) * sin (az)); - dlp = sqrt ((dist * dist) + (rad * rad) + (2.0 * dist * rad * sin (azp))); - l = sqrt ((dist * dist) - (rad * rad)); - al = (0.5 * M_PI) + azp; - if (dlp > l) - dlp = l + (rad * (al - acos (rad / dist))); - return (dlp / 343.3); -} - -// Calculate the effective head-related time delays for each minimum-phase -// HRIR. -static void CalculateHrtds (const HeadModelT model, const double radius, HrirDataT * hData) { - double minHrtd, maxHrtd; - uint e, a, j; - double t; - - minHrtd = 1000.0; - maxHrtd = -1000.0; - for (e = 0; e < hData -> mEvCount; e ++) { - for (a = 0; a < hData -> mAzCount [e]; a ++) { - j = hData -> mEvOffset [e] + a; - if (model == HM_DATASET) { - t = hData -> mHrtds [j] * radius / hData -> mRadius; - } else { - t = CalcLTD ((-90.0 + (e * 180.0 / (hData -> mEvCount - 1))) * M_PI / 180.0, - (a * 360.0 / hData -> mAzCount [e]) * M_PI / 180.0, - radius, hData -> mDistance); - } - hData -> mHrtds [j] = t; - maxHrtd = fmax (t, maxHrtd); - minHrtd = fmin (t, minHrtd); - } - } - maxHrtd -= minHrtd; - for (j = 0; j < hData -> mIrCount; j ++) - hData -> mHrtds [j] -= minHrtd; - hData -> mMaxHrtd = maxHrtd; -} - -// Store the OpenAL Soft HRTF data set. -static int StoreMhr (const HrirDataT * hData, const char * filename) { - FILE * fp = NULL; - uint e, step, end, n, j, i; - int hpHist, v; - - if ((fp = fopen (filename, "wb")) == NULL) { - fprintf (stderr, "Error: Could not open MHR file '%s'.\n", filename); - return (0); - } - if (! WriteAscii (MHR_FORMAT, fp, filename)) - return (0); - if (! WriteBin4 (BO_LITTLE, 4, (uint32) hData -> mIrRate, fp, filename)) - return (0); - if (! WriteBin4 (BO_LITTLE, 1, (uint32) hData -> mIrPoints, fp, filename)) - return (0); - if (! WriteBin4 (BO_LITTLE, 1, (uint32) hData -> mEvCount, fp, filename)) - return (0); - for (e = 0; e < hData -> mEvCount; e ++) { - if (! WriteBin4 (BO_LITTLE, 1, (uint32) hData -> mAzCount [e], fp, filename)) - return (0); - } - step = hData -> mIrSize; - end = hData -> mIrCount * step; - n = hData -> mIrPoints; - srand (0x31DF840C); - for (j = 0; j < end; j += step) { - hpHist = 0; - for (i = 0; i < n; i ++) { - v = HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist); - if (! WriteBin4 (BO_LITTLE, 2, (uint32) v, fp, filename)) - return (0); - } - } - for (j = 0; j < hData -> mIrCount; j ++) { - v = (int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]), MAX_HRTD); - if (! WriteBin4 (BO_LITTLE, 1, (uint32) v, fp, filename)) - return (0); - } - fclose (fp); - return (1); -} - -// Store the OpenAL Soft built-in table. -static int StoreTable (const HrirDataT * hData, const char * filename) { - FILE * fp = NULL; - uint step, end, n, j, i; - int hpHist, v; - char text [128 + 1]; - - if ((fp = fopen (filename, "wb")) == NULL) { - fprintf (stderr, "Error: Could not open table file '%s'.\n", filename); - return (0); - } - snprintf (text, 128, "/* Elevation metrics */\n" - "static const ALubyte defaultAzCount[%u] = { ", hData -> mEvCount); - if (! WriteAscii (text, fp, filename)) - return (0); - for (i = 0; i < hData -> mEvCount; i ++) { - snprintf (text, 128, "%u, ", hData -> mAzCount [i]); - if (! WriteAscii (text, fp, filename)) - return (0); - } - snprintf (text, 128, "};\n" - "static const ALushort defaultEvOffset[%u] = { ", hData -> mEvCount); - if (! WriteAscii (text, fp, filename)) - return (0); - for (i = 0; i < hData -> mEvCount; i ++) { - snprintf (text, 128, "%u, ", hData -> mEvOffset [i]); - if (! WriteAscii (text, fp, filename)) - return (0); - } - step = hData -> mIrSize; - end = hData -> mIrCount * step; - n = hData -> mIrPoints; - snprintf (text, 128, "};\n\n" - "/* HRIR Coefficients */\n" - "static const ALshort defaultCoeffs[%u] =\n{\n", hData -> mIrCount * n); - if (! WriteAscii (text, fp, filename)) - return (0); - srand (0x31DF840C); - for (j = 0; j < end; j += step) { - if (! WriteAscii (" ", fp, filename)) - return (0); - hpHist = 0; - for (i = 0; i < n; i ++) { - v = HpTpdfDither (32767.0 * hData -> mHrirs [j + i], & hpHist); - snprintf (text, 128, " %+d,", v); - if (! WriteAscii (text, fp, filename)) - return (0); - } - if (! WriteAscii ("\n", fp, filename)) - return (0); - } - snprintf (text, 128, "};\n\n" - "/* HRIR Delays */\n" - "static const ALubyte defaultDelays[%u] =\n{\n" - " ", hData -> mIrCount); - if (! WriteAscii (text, fp, filename)) - return (0); - for (j = 0; j < hData -> mIrCount; j ++) { - v = (int) fmin (round (hData -> mIrRate * hData -> mHrtds [j]), MAX_HRTD); - snprintf (text, 128, " %d,", v); - if (! WriteAscii (text, fp, filename)) - return (0); - } - if (! WriteAscii ("\n};\n\n" - "/* Default HRTF Definition */\n", fp, filename)) - return (0); - snprintf (text, 128, "static const struct Hrtf DefaultHrtf = {\n" - " %u, %u, %u, defaultAzCount, defaultEvOffset,\n", - hData -> mIrRate, hData -> mIrPoints, hData -> mEvCount); - if (! WriteAscii (text, fp, filename)) - return (0); - if (! WriteAscii (" defaultCoeffs, defaultDelays, NULL\n" - "};\n", fp, filename)) - return (0); - fclose (fp); - return (1); -} - -// Process the data set definition to read and validate the data set metrics. -static int ProcessMetrics (TokenReaderT * tr, const uint fftSize, const uint truncSize, HrirDataT * hData) { - char ident [MAX_IDENT_LEN + 1]; - uint line, col; - int intVal; - uint points; - double fpVal; - int hasRate = 0, hasPoints = 0, hasAzimuths = 0; - int hasRadius = 0, hasDistance = 0; - - while (! (hasRate && hasPoints && hasAzimuths && hasRadius && hasDistance)) { - TrIndication (tr, & line, & col); - if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) - return (0); - if (strcasecmp (ident, "rate") == 0) { - if (hasRate) { - TrErrorAt (tr, line, col, "Redefinition of 'rate'.\n"); - return (0); - } - if (! TrReadOperator (tr, "=")) - return (0); - if (! TrReadInt (tr, MIN_RATE, MAX_RATE, & intVal)) - return (0); - hData -> mIrRate = (uint) intVal; - hasRate = 1; - } else if (strcasecmp (ident, "points") == 0) { - if (hasPoints) { - TrErrorAt (tr, line, col, "Redefinition of 'points'.\n"); - return (0); - } - if (! TrReadOperator (tr, "=")) - return (0); - TrIndication (tr, & line, & col); - if (! TrReadInt (tr, MIN_POINTS, MAX_POINTS, & intVal)) - return (0); - points = (uint) intVal; - if ((fftSize > 0) && (points > fftSize)) { - TrErrorAt (tr, line, col, "Value exceeds the overridden FFT size.\n"); - return (0); - } - if (points < truncSize) { - TrErrorAt (tr, line, col, "Value is below the truncation size.\n"); - return (0); - } - hData -> mIrPoints = points; - hData -> mFftSize = fftSize; - if (fftSize <= 0) { - points = 1; - while (points < (4 * hData -> mIrPoints)) - points <<= 1; - hData -> mFftSize = points; - hData -> mIrSize = 1 + (points / 2); - } else { - hData -> mFftSize = fftSize; - hData -> mIrSize = 1 + (fftSize / 2); - if (points > hData -> mIrSize) - hData -> mIrSize = points; - } - hasPoints = 1; - } else if (strcasecmp (ident, "azimuths") == 0) { - if (hasAzimuths) { - TrErrorAt (tr, line, col, "Redefinition of 'azimuths'.\n"); - return (0); - } - if (! TrReadOperator (tr, "=")) - return (0); - hData -> mIrCount = 0; - hData -> mEvCount = 0; - hData -> mEvOffset [0] = 0; - for (;;) { - if (! TrReadInt (tr, MIN_AZ_COUNT, MAX_AZ_COUNT, & intVal)) - return (0); - hData -> mAzCount [hData -> mEvCount] = (uint) intVal; - hData -> mIrCount += (uint) intVal; - hData -> mEvCount ++; - if (! TrIsOperator (tr, ",")) - break; - if (hData -> mEvCount >= MAX_EV_COUNT) { - TrError (tr, "Exceeded the maximum of %d elevations.\n", MAX_EV_COUNT); - return (0); - } - hData -> mEvOffset [hData -> mEvCount] = hData -> mEvOffset [hData -> mEvCount - 1] + ((uint) intVal); - TrReadOperator (tr, ","); - } - if (hData -> mEvCount < MIN_EV_COUNT) { - TrErrorAt (tr, line, col, "Did not reach the minimum of %d azimuth counts.\n", MIN_EV_COUNT); - return (0); - } - hasAzimuths = 1; - } else if (strcasecmp (ident, "radius") == 0) { - if (hasRadius) { - TrErrorAt (tr, line, col, "Redefinition of 'radius'.\n"); - return (0); - } - if (! TrReadOperator (tr, "=")) - return (0); - if (! TrReadFloat (tr, MIN_RADIUS, MAX_RADIUS, & fpVal)) - return (0); - hData -> mRadius = fpVal; - hasRadius = 1; - } else if (strcasecmp (ident, "distance") == 0) { - if (hasDistance) { - TrErrorAt (tr, line, col, "Redefinition of 'distance'.\n"); - return (0); - } - if (! TrReadOperator (tr, "=")) - return (0); - if (! TrReadFloat (tr, MIN_DISTANCE, MAX_DISTANCE, & fpVal)) - return (0); - hData -> mDistance = fpVal; - hasDistance = 1; - } else { - TrErrorAt (tr, line, col, "Expected a metric name.\n"); - return (0); - } - TrSkipWhitespace (tr); - } - return (1); -} - -// Parse an index pair from the data set definition. -static int ReadIndexPair (TokenReaderT * tr, const HrirDataT * hData, uint * ei, uint * ai) { - int intVal; - - if (! TrReadInt (tr, 0, (int) hData -> mEvCount, & intVal)) - return (0); - (* ei) = (uint) intVal; - if (! TrReadOperator (tr, ",")) - return (0); - if (! TrReadInt (tr, 0, (int) hData -> mAzCount [(* ei)], & intVal)) - return (0); - (* ai) = (uint) intVal; - return (1); -} - -// Match the source format from a given identifier. -static SourceFormatT MatchSourceFormat (const char * ident) { - if (strcasecmp (ident, "wave") == 0) - return (SF_WAVE); - else if (strcasecmp (ident, "bin_le") == 0) - return (SF_BIN_LE); - else if (strcasecmp (ident, "bin_be") == 0) - return (SF_BIN_BE); - else if (strcasecmp (ident, "ascii") == 0) - return (SF_ASCII); - return (SF_NONE); -} - -// Match the source element type from a given identifier. -static ElementTypeT MatchElementType (const char * ident) { - if (strcasecmp (ident, "int") == 0) - return (ET_INT); - else if (strcasecmp (ident, "fp") == 0) - return (ET_FP); - return (ET_NONE); -} - -// Parse and validate a source reference from the data set definition. -static int ReadSourceRef (TokenReaderT * tr, SourceRefT * src) { - uint line, col; - char ident [MAX_IDENT_LEN + 1]; - int intVal; - - TrIndication (tr, & line, & col); - if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) - return (0); - src -> mFormat = MatchSourceFormat (ident); - if (src -> mFormat == SF_NONE) { - TrErrorAt (tr, line, col, "Expected a source format.\n"); - return (0); - } - if (! TrReadOperator (tr, "(")) - return (0); - if (src -> mFormat == SF_WAVE) { - if (! TrReadInt (tr, 0, MAX_WAVE_CHANNELS, & intVal)) - return (0); - src -> mType = ET_NONE; - src -> mSize = 0; - src -> mBits = 0; - src -> mChannel = (uint) intVal; - src -> mSkip = 0; - } else { - TrIndication (tr, & line, & col); - if (! TrReadIdent (tr, MAX_IDENT_LEN, ident)) - return (0); - src -> mType = MatchElementType (ident); - if (src -> mType == ET_NONE) { - TrErrorAt (tr, line, col, "Expected a source element type.\n"); - return (0); - } - if ((src -> mFormat == SF_BIN_LE) || (src -> mFormat == SF_BIN_BE)) { - if (! TrReadOperator (tr, ",")) - return (0); - if (src -> mType == ET_INT) { - if (! TrReadInt (tr, MIN_BIN_SIZE, MAX_BIN_SIZE, & intVal)) - return (0); - src -> mSize = (uint) intVal; - if (TrIsOperator (tr, ",")) { - TrReadOperator (tr, ","); - TrIndication (tr, & line, & col); - if (! TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal)) - return (0); - if ((abs (intVal) < MIN_BIN_BITS) || (((uint) abs (intVal)) > (8 * src -> mSize))) { - TrErrorAt (tr, line, col, "Expected a value of (+/-) %d to %d.\n", MIN_BIN_BITS, 8 * src -> mSize); - return (0); - } - src -> mBits = intVal; - } else { - src -> mBits = (int) (8 * src -> mSize); - } - } else { - TrIndication (tr, & line, & col); - if (! TrReadInt (tr, -2147483647 - 1, 2147483647, & intVal)) - return (0); - if ((intVal != 4) && (intVal != 8)) { - TrErrorAt (tr, line, col, "Expected a value of 4 or 8.\n"); - return (0); - } - src -> mSize = (uint) intVal; - src -> mBits = 0; - } - } else if ((src -> mFormat == SF_ASCII) && (src -> mType == ET_INT)) { - if (! TrReadOperator (tr, ",")) - return (0); - if (! TrReadInt (tr, MIN_ASCII_BITS, MAX_ASCII_BITS, & intVal)) - return (0); - src -> mSize = 0; - src -> mBits = intVal; - } else { - src -> mSize = 0; - src -> mBits = 0; - } - if (TrIsOperator (tr, ";")) { - TrReadOperator (tr, ";"); - if (! TrReadInt (tr, 0, 0x7FFFFFFF, & intVal)) - return (0); - src -> mSkip = (uint) intVal; - } else { - src -> mSkip = 0; - } - } - if (! TrReadOperator (tr, ")")) - return (0); - if (TrIsOperator (tr, "@")) { - TrReadOperator (tr, "@"); - if (! TrReadInt (tr, 0, 0x7FFFFFFF, & intVal)) - return (0); - src -> mOffset = (uint) intVal; - } else { - src -> mOffset = 0; - } - if (! TrReadOperator (tr, ":")) - return (0); - if (! TrReadString (tr, MAX_PATH_LEN, src -> mPath)) - return (0); - return (1); -} - -// Process the list of sources in the data set definition. -static int ProcessSources (const HeadModelT model, TokenReaderT * tr, HrirDataT * hData) { - uint * setCount = NULL, * setFlag = NULL; - double * hrir = NULL; - uint line, col, ei, ai; - SourceRefT src; - double factor; - - setCount = (uint *) calloc (hData -> mEvCount, sizeof (uint)); - setFlag = (uint *) calloc (hData -> mIrCount, sizeof (uint)); - hrir = CreateArray (hData -> mIrPoints); - while (TrIsOperator (tr, "[")) { - TrIndication (tr, & line, & col); - TrReadOperator (tr, "["); - if (ReadIndexPair (tr, hData, & ei, & ai)) { - if (TrReadOperator (tr, "]")) { - if (! setFlag [hData -> mEvOffset [ei] + ai]) { - if (TrReadOperator (tr, "=")) { - factor = 1.0; - for (;;) { - if (ReadSourceRef (tr, & src)) { - if (LoadSource (& src, hData -> mIrRate, hData -> mIrPoints, hrir)) { - if (model == HM_DATASET) - AverageHrirOnset (hrir, 1.0 / factor, ei, ai, hData); - AverageHrirMagnitude (hrir, 1.0 / factor, ei, ai, hData); - factor += 1.0; - if (! TrIsOperator (tr, "+")) - break; - TrReadOperator (tr, "+"); - continue; - } - } - DestroyArray (hrir); - free (setFlag); - free (setCount); - return (0); - } - setFlag [hData -> mEvOffset [ei] + ai] = 1; - setCount [ei] ++; - continue; - } - } else { - TrErrorAt (tr, line, col, "Redefinition of source.\n"); - } - } - } - DestroyArray (hrir); - free (setFlag); - free (setCount); - return (0); - } - ei = 0; - while ((ei < hData -> mEvCount) && (setCount [ei] < 1)) - ei ++; - if (ei < hData -> mEvCount) { - hData -> mEvStart = ei; - while ((ei < hData -> mEvCount) && (setCount [ei] == hData -> mAzCount [ei])) - ei ++; - if (ei >= hData -> mEvCount) { - if (! TrLoad (tr)) { - DestroyArray (hrir); - free (setFlag); - free (setCount); - return (1); - } else { - TrError (tr, "Errant data at end of source list.\n"); - } - } else { - TrError (tr, "Missing sources for elevation index %d.\n", ei); - } - } else { - TrError (tr, "Missing source references.\n"); - } - DestroyArray (hrir); - free (setFlag); - free (setCount); - return (0); -} - -/* Parse the data set definition and process the source data, storing the - * resulting data set as desired. If the input name is NULL it will read - * from standard input. - */ -static int ProcessDefinition (const char * inName, const uint outRate, const uint fftSize, const int equalize, const int surface, const double limit, const uint truncSize, const HeadModelT model, const double radius, const OutputFormatT outFormat, const char * outName) { - FILE * fp = NULL; - TokenReaderT tr; - HrirDataT hData; - double * dfa = NULL; - char rateStr [8 + 1], expName [MAX_PATH_LEN]; - - hData . mIrRate = 0; - hData . mIrPoints = 0; - hData . mFftSize = 0; - hData . mIrSize = 0; - hData . mIrCount = 0; - hData . mEvCount = 0; - hData . mRadius = 0; - hData . mDistance = 0; - fprintf (stdout, "Reading HRIR definition...\n"); - if (inName != NULL) { - fp = fopen (inName, "r"); - if (fp == NULL) { - fprintf (stderr, "Error: Could not open definition file '%s'\n", inName); - return (0); - } - TrSetup (fp, inName, & tr); - } else { - fp = stdin; - TrSetup (fp, "", & tr); - } - if (! ProcessMetrics (& tr, fftSize, truncSize, & hData)) { - if (inName != NULL) - fclose (fp); - return (0); - } - hData . mHrirs = CreateArray (hData . mIrCount * hData . mIrSize); - hData . mHrtds = CreateArray (hData . mIrCount); - if (! ProcessSources (model, & tr, & hData)) { - DestroyArray (hData . mHrtds); - DestroyArray (hData . mHrirs); - if (inName != NULL) - fclose (fp); - return (0); - } - if (inName != NULL) - fclose (fp); - if (equalize) { - dfa = CreateArray (1 + (hData . mFftSize / 2)); - fprintf (stdout, "Calculating diffuse-field average...\n"); - CalculateDiffuseFieldAverage (& hData, surface, limit, dfa); - fprintf (stdout, "Performing diffuse-field equalization...\n"); - DiffuseFieldEqualize (dfa, & hData); - DestroyArray (dfa); - } - fprintf (stdout, "Performing minimum phase reconstruction...\n"); - ReconstructHrirs (& hData); - if ((outRate != 0) && (outRate != hData . mIrRate)) { - fprintf (stdout, "Resampling HRIRs...\n"); - ResampleHrirs (outRate, & hData); - } - fprintf (stdout, "Truncating minimum-phase HRIRs...\n"); - hData . mIrPoints = truncSize; - fprintf (stdout, "Synthesizing missing elevations...\n"); - if (model == HM_DATASET) - SynthesizeOnsets (& hData); - SynthesizeHrirs (& hData); - fprintf (stdout, "Normalizing final HRIRs...\n"); - NormalizeHrirs (& hData); - fprintf (stdout, "Calculating impulse delays...\n"); - CalculateHrtds (model, (radius > DEFAULT_CUSTOM_RADIUS) ? radius : hData . mRadius, & hData); - snprintf (rateStr, 8, "%u", hData . mIrRate); - StrSubst (outName, "%r", rateStr, MAX_PATH_LEN, expName); - switch (outFormat) { - case OF_MHR : - fprintf (stdout, "Creating MHR data set file...\n"); - if (! StoreMhr (& hData, expName)) - return (0); - break; - case OF_TABLE : - fprintf (stderr, "Creating OpenAL Soft table file...\n"); - if (! StoreTable (& hData, expName)) - return (0); - break; - default : - break; - } - DestroyArray (hData . mHrtds); - DestroyArray (hData . mHrirs); - return (1); -} - -// Standard command line dispatch. -int main (const int argc, const char * argv []) { - const char * inName = NULL, * outName = NULL; - OutputFormatT outFormat; - int argi; - uint outRate, fftSize; - int equalize, surface; - double limit; - uint truncSize; - HeadModelT model; - double radius; - char * end = NULL; - - if (argc < 2) { - fprintf (stderr, "Error: No command specified. See '%s -h' for help.\n", argv [0]); - return (-1); - } - if ((strcmp (argv [1], "--help") == 0) || (strcmp (argv [1], "-h") == 0)) { - fprintf (stdout, "HRTF Processing and Composition Utility\n\n"); - fprintf (stdout, "Usage: %s [