2 * OpenAL cross platform audio library
3 * Copyright (C) 2009 by Chris Robinson.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
28 #include "alAuxEffectSlot.h"
33 typedef struct ALmodulatorState
{
34 // Must be first in all effects!
46 ALfloat Gain
[MaxChannels
];
52 #define WAVEFORM_FRACBITS 16
53 #define WAVEFORM_FRACONE (1<<WAVEFORM_FRACBITS)
54 #define WAVEFORM_FRACMASK (WAVEFORM_FRACONE-1)
56 static __inline ALfloat
Sin(ALuint index
)
58 return sinf(index
* (F_PI
*2.0f
/ WAVEFORM_FRACONE
));
61 static __inline ALfloat
Saw(ALuint index
)
63 return index
*(2.0f
/WAVEFORM_FRACONE
) - 1.0f
;
66 static __inline ALfloat
Square(ALuint index
)
68 return ((index
>>(WAVEFORM_FRACBITS
-1))&1)*2.0f
- 1.0f
;
72 static __inline ALfloat
hpFilter1P(FILTER
*iir
, ALuint offset
, ALfloat input
)
74 ALfloat
*history
= &iir
->history
[offset
];
75 ALfloat a
= iir
->coeff
;
76 ALfloat output
= input
;
78 output
= output
+ (history
[0]-output
)*a
;
81 return input
- output
;
85 #define DECL_TEMPLATE(func) \
86 static void Process##func(ALmodulatorState *state, ALuint SamplesToDo, \
87 const ALfloat *RESTRICT SamplesIn, \
88 ALfloat (*RESTRICT SamplesOut)[BUFFERSIZE]) \
90 const ALuint step = state->step; \
91 ALuint index = state->index; \
95 for(i = 0;i < SamplesToDo;i++) \
97 samp = SamplesIn[i]; \
100 index &= WAVEFORM_FRACMASK; \
101 samp *= func(index); \
103 samp = hpFilter1P(&state->iirFilter, 0, samp); \
105 for(k = 0;k < MaxChannels;k++) \
106 SamplesOut[k][i] += state->Gain[k] * samp; \
108 state->index = index; \
113 DECL_TEMPLATE(Square
)
118 static ALvoid
ModulatorDestroy(ALeffectState
*effect
)
120 ALmodulatorState
*state
= (ALmodulatorState
*)effect
;
124 static ALboolean
ModulatorDeviceUpdate(ALeffectState
*effect
, ALCdevice
*Device
)
131 static ALvoid
ModulatorUpdate(ALeffectState
*effect
, ALCdevice
*Device
, const ALeffectslot
*Slot
)
133 ALmodulatorState
*state
= (ALmodulatorState
*)effect
;
134 ALfloat gain
, cw
, a
= 0.0f
;
137 if(Slot
->effect
.Modulator
.Waveform
== AL_RING_MODULATOR_SINUSOID
)
138 state
->Waveform
= SINUSOID
;
139 else if(Slot
->effect
.Modulator
.Waveform
== AL_RING_MODULATOR_SAWTOOTH
)
140 state
->Waveform
= SAWTOOTH
;
141 else if(Slot
->effect
.Modulator
.Waveform
== AL_RING_MODULATOR_SQUARE
)
142 state
->Waveform
= SQUARE
;
144 state
->step
= fastf2u(Slot
->effect
.Modulator
.Frequency
*WAVEFORM_FRACONE
/
146 if(state
->step
== 0) state
->step
= 1;
148 cw
= cosf(F_PI
*2.0f
* Slot
->effect
.Modulator
.HighPassCutoff
/
150 a
= (2.0f
-cw
) - sqrtf(powf(2.0f
-cw
, 2.0f
) - 1.0f
);
151 state
->iirFilter
.coeff
= a
;
153 gain
= sqrtf(1.0f
/Device
->NumChan
);
155 for(index
= 0;index
< MaxChannels
;index
++)
156 state
->Gain
[index
] = 0.0f
;
157 for(index
= 0;index
< Device
->NumChan
;index
++)
159 enum Channel chan
= Device
->Speaker2Chan
[index
];
160 state
->Gain
[chan
] = gain
;
164 static ALvoid
ModulatorProcess(ALeffectState
*effect
, ALuint SamplesToDo
, const ALfloat
*RESTRICT SamplesIn
, ALfloat (*RESTRICT SamplesOut
)[BUFFERSIZE
])
166 ALmodulatorState
*state
= (ALmodulatorState
*)effect
;
168 switch(state
->Waveform
)
171 ProcessSin(state
, SamplesToDo
, SamplesIn
, SamplesOut
);
175 ProcessSaw(state
, SamplesToDo
, SamplesIn
, SamplesOut
);
179 ProcessSquare(state
, SamplesToDo
, SamplesIn
, SamplesOut
);
184 ALeffectState
*ModulatorCreate(void)
186 ALmodulatorState
*state
;
188 state
= malloc(sizeof(*state
));
192 state
->state
.Destroy
= ModulatorDestroy
;
193 state
->state
.DeviceUpdate
= ModulatorDeviceUpdate
;
194 state
->state
.Update
= ModulatorUpdate
;
195 state
->state
.Process
= ModulatorProcess
;
200 state
->iirFilter
.coeff
= 0.0f
;
201 state
->iirFilter
.history
[0] = 0.0f
;
203 return &state
->state
;