Add methods to get and set modulator properties on fontsounds
This commit is contained in:
@@ -303,6 +303,8 @@ static const ALCfunction alcFunctions[] = {
|
||||
DECL(alFontsound2iSOFT),
|
||||
DECL(alFontsoundivSOFT),
|
||||
DECL(alGetFontsoundivSOFT),
|
||||
DECL(alFontsoundModulatoriSOFT),
|
||||
DECL(alGetFontsoundModulatorivSOFT),
|
||||
DECL(alMidiSoundfontSOFT),
|
||||
DECL(alMidiSoundfontvSOFT),
|
||||
DECL(alMidiEventSOFT),
|
||||
|
||||
+52
-1
@@ -714,6 +714,27 @@ static ALboolean checkZone(const GenModList *zone, const PresetHeader *preset, c
|
||||
return AL_TRUE;
|
||||
}
|
||||
|
||||
static ALenum getModSrcInput(int type)
|
||||
{
|
||||
if(type == 0) return AL_ONE_SOFT;
|
||||
if(type == 2) return AL_NOTEON_VELOCITY_SOFT;
|
||||
if(type == 3) return AL_NOTEON_KEY_SOFT;
|
||||
if(type == 10) return AL_AFTERTOUCH_SOFT;
|
||||
if(type == 13) return AL_CHANNELPRESSURE_SOFT;
|
||||
if(type == 14) return AL_PITCHBEND_SOFT;
|
||||
if(type == 16) return AL_PITCHBEND_SENSITIVITY_SOFT;
|
||||
if((type&0x80))
|
||||
{
|
||||
type ^= 0x80;
|
||||
if(type > 0 && type < 120 && !(type == 6 || (type >= 32 && type <= 63) ||
|
||||
(type >= 98 && type <= 101)))
|
||||
return type;
|
||||
type ^= 0x80;
|
||||
}
|
||||
ERR("Unhandled modulator source input: 0x%02x\n", type);
|
||||
return AL_NONE;
|
||||
}
|
||||
|
||||
static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *zone)
|
||||
{
|
||||
static const ALenum Gen2Param[60] = {
|
||||
@@ -782,7 +803,37 @@ static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *
|
||||
|
||||
if(zone->mods)
|
||||
{
|
||||
/* FIXME: Handle modulators */
|
||||
ALsizei i;
|
||||
for(i = 0;i < zone->mods_size;i++)
|
||||
{
|
||||
ALenum src0in = getModSrcInput(zone->mods[i].mSrcOp&0xFF);
|
||||
ALenum src0form = (zone->mods[i].mSrcOp&0xFC00);
|
||||
ALenum src1in = getModSrcInput(zone->mods[i].mAmtSrcOp&0xFF);
|
||||
ALenum src1form = (zone->mods[i].mAmtSrcOp&0xFC00);
|
||||
ALenum trans = zone->mods[i].mTransOp;
|
||||
ALenum dst = (zone->mods[i].mDstOp < 60) ? Gen2Param[zone->mods[i].mDstOp] : 0;
|
||||
if(!dst)
|
||||
ERR("Unhandled modulator destination: %d\n", zone->mods[i].mDstOp);
|
||||
if((src0form&0xF000))
|
||||
ERR("Unhandled modulator source form: 0x%04x\n", src0form);
|
||||
if((src1form&0xF000))
|
||||
ERR("Unhandled modulator source form: 0x%04x\n", src1form);
|
||||
if(!(trans == 0 || trans == 2))
|
||||
ERR("Unhandled modulator transform: %d\n", trans);
|
||||
if(src0in && !(src0form&0xF000) && src1in && !(src1form&0xF000) &&
|
||||
(trans == 0 || trans == 2) && dst)
|
||||
{
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_INPUT_SOFT, src0in);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_TYPE_SOFT, (zone->mods[i].mSrcOp&0x300));
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE0_FORM_SOFT, src0form);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_INPUT_SOFT, src1in);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_TYPE_SOFT, (zone->mods[i].mAmtSrcOp&0x300));
|
||||
ALfontsound_setModStagei(sound, context, i, AL_SOURCE1_FORM_SOFT, src1form);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_AMOUNT_SOFT, zone->mods[i].mAmount);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_TRANSFORM_OP_SOFT, trans);
|
||||
ALfontsound_setModStagei(sound, context, i, AL_DESTINATION_SOFT, dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gen = zone->gens;
|
||||
|
||||
@@ -39,6 +39,43 @@
|
||||
#define AL_PRESETS_SOFT 0x9992
|
||||
#define AL_FONTSOUNDS_SIZE_SOFT 0x9991
|
||||
#define AL_FONTSOUNDS_SOFT 0x9990
|
||||
|
||||
#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 Input */
|
||||
#define AL_ONE_SOFT 0x0080
|
||||
#define AL_NOTEON_VELOCITY_SOFT 0x0082
|
||||
#define AL_NOTEON_KEY_SOFT 0x0083
|
||||
/* aftertouch */
|
||||
/* channelpressure */
|
||||
/* pitchbend */
|
||||
#define AL_PITCHBEND_SENSITIVITY_SOFT 0x0090
|
||||
/* 0...127 CC */
|
||||
|
||||
/* Source Type */
|
||||
#define AL_UNORM_SOFT 0x0000
|
||||
#define AL_SNORM_SOFT 0x0100
|
||||
#define AL_UNORM_REV_SOFT 0x0200
|
||||
#define AL_SNORM_REV_SOFT 0x0300
|
||||
|
||||
/* Source Form */
|
||||
#define AL_LINEAR_SOFT 0x0000
|
||||
#define AL_CONCAVE_SOFT 0x0400
|
||||
#define AL_CONVEX_SOFT 0x0800
|
||||
#define AL_SWITCH_SOFT 0x0C00
|
||||
|
||||
/* Transform op */
|
||||
/* linear */
|
||||
#define AL_ABSOLUTE_SOFT 0x0002
|
||||
|
||||
#define AL_SAMPLE_START_SOFT 0x2000
|
||||
#define AL_SAMPLE_END_SOFT 0x2001
|
||||
#define AL_SAMPLE_LOOP_START_SOFT 0x2002
|
||||
@@ -119,6 +156,8 @@ typedef void (AL_APIENTRY*LPALFONTSOUNDISOFT)(ALuint id, ALenum param, ALint val
|
||||
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);
|
||||
@@ -156,6 +195,8 @@ 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);
|
||||
|
||||
@@ -9,11 +9,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct ALsfmodulator {
|
||||
ALenum SourceOp;
|
||||
ALenum DestOp;
|
||||
struct {
|
||||
ALenum Input;
|
||||
ALenum Type;
|
||||
ALenum Form;
|
||||
} Source[2];
|
||||
ALint Amount;
|
||||
ALenum AmountSourceOp;
|
||||
ALenum TransformOp;
|
||||
ALenum Dest;
|
||||
} ALsfmodulator;
|
||||
|
||||
|
||||
@@ -96,6 +99,7 @@ typedef struct ALfontsound {
|
||||
|
||||
void ALfontsound_Destruct(ALfontsound *self);
|
||||
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);
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ extern inline struct ALfontsound *RemoveFontsound(ALCdevice *device, ALuint id);
|
||||
static void ALfontsound_Construct(ALfontsound *self);
|
||||
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);
|
||||
|
||||
|
||||
AL_API void AL_APIENTRY alGenFontsoundsSOFT(ALsizei n, ALuint *ids)
|
||||
@@ -439,6 +442,42 @@ 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)
|
||||
{
|
||||
@@ -766,6 +805,152 @@ void ALfontsound_setPropi(ALfontsound *self, ALCcontext *context, ALenum param,
|
||||
}
|
||||
}
|
||||
|
||||
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(*ret));
|
||||
InsertUIntMapEntry(&self->ModulatorMap, stage, ret);
|
||||
*ret = moddef;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ALfontsound_setModStagei(ALfontsound *self, ALCcontext *context, ALsizei stage, ALenum param, ALint value)
|
||||
{
|
||||
ALint srcidx = 0;
|
||||
|
||||
if(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_AFTERTOUCH_SOFT ||
|
||||
value == AL_CHANNELPRESSURE_SOFT || value == AL_PITCHBEND_SOFT ||
|
||||
value == AL_PITCHBEND_SENSITIVITY_SOFT ||
|
||||
(value > 0 && value < 120 && !(value == 6 || (value >= 32 && value <= 63) ||
|
||||
(value >= 98 && value <= 101))
|
||||
)
|
||||
))
|
||||
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_SNORM_SOFT ||
|
||||
value == AL_UNORM_REV_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_CONVEX_SOFT ||
|
||||
value == AL_CONCAVE_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
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user