blob: cd1489144268d21dda956e4b390fc2a98c7d280d [file] [log] [blame]
Eric Laurent135ad072010-05-21 06:05:13 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_EFFECTREVERB_H_
18#define ANDROID_EFFECTREVERB_H_
19
20#include <media/EffectReverbApi.h>
21
22
23/*------------------------------------
24 * defines
25 *------------------------------------
26*/
27
28/*
29CIRCULAR() calculates the array index using modulo arithmetic.
30The "trick" is that modulo arithmetic is simplified by masking
31the effective address where the mask is (2^n)-1. This only works
32if the buffer size is a power of two.
33*/
34#define CIRCULAR(base,offset,size) (uint32_t)( \
35 ( \
36 ((int32_t)(base)) + ((int32_t)(offset)) \
37 ) \
38 & size \
39 )
40
41#define NUM_OUTPUT_CHANNELS 2
42#define OUTPUT_CHANNELS CHANNEL_STEREO
43
44#define REVERB_BUFFER_SIZE_IN_SAMPLES_MAX 16384
45
46#define REVERB_MAX_ROOM_TYPE 4 // any room numbers larger than this are invalid
47#define REVERB_MAX_NUM_REFLECTIONS 5 // max num reflections per channel
48
49
50// xfade parameters
51#define REVERB_XFADE_PERIOD_IN_SECONDS (double) (100.0 / 1000.0) // xfade once every this many seconds
52
53
54/**********/
55/* the entire synth uses various flags in a bit field */
56
57/* if flag is set, synth reset has been requested */
58#define REVERB_FLAG_RESET_IS_REQUESTED 0x01 /* bit 0 */
59#define MASK_REVERB_RESET_IS_REQUESTED 0x01
60#define MASK_REVERB_RESET_IS_NOT_REQUESTED (uint32_t)(~MASK_REVERB_RESET_IS_REQUESTED)
61
62/*
63by default, we always want to update ALL channel parameters
64when we reset the synth (e.g., during GM ON)
65*/
66#define DEFAULT_REVERB_FLAGS 0x0
67
68/* coefficients for generating sin, cos */
69#define REVERB_PAN_G2 4294940151 /* -0.82842712474619 = 2 - 4/sqrt(2) */
70/*
71int32_t nPanG1 = +1.0 for sin
72int32_t nPanG1 = -1.0 for cos
73*/
74#define REVERB_PAN_G0 23170 /* 0.707106781186547 = 1/sqrt(2) */
75
76/*************************************************************/
77// define the input injection points
78#define GUARD 5 // safety guard of this many samples
79
80#define MAX_AP_TIME (int) ((20*65536)/1000) // delay time in time units (65536th of sec)
81#define MAX_DELAY_TIME (int) ((65*65536)/1000) // delay time in time units
82#define MAX_EARLY_TIME (int) ((65*65536)/1000) // delay time in time units
83
84#define AP0_IN 0
85
86
87#define REVERB_DEFAULT_ROOM_NUMBER 1 // default preset number
88#define DEFAULT_AP0_GAIN 19400
89#define DEFAULT_AP1_GAIN -19400
90
91#define REVERB_DEFAULT_WET 32767
92#define REVERB_DEFAULT_DRY 0
93
94#define REVERB_WET_MAX 32767
95#define REVERB_WET_MIN 0
96#define REVERB_DRY_MAX 32767
97#define REVERB_DRY_MIN 0
98
99// constants for reverb density
100// The density expressed in permilles changes the Allpass delay in a linear manner in the range defined by
101// AP0_TIME_BASE to AP0_TIME_BASE + AP0_TIME_RANGE
102#define AP0_TIME_BASE (int)((9*65536)/1000)
103#define AP0_TIME_RANGE (int)((4*65536)/1000)
104#define AP1_TIME_BASE (int)((12*65536)/1000)
105#define AP1_TIME_RANGE (int)((8*65536)/1000)
106
107// constants for reverb diffusion
108// The diffusion expressed in permilles changes the Allpass gain in a linear manner in the range defined by
109// AP0_GAIN_BASE to AP0_GAIN_BASE + AP0_GAIN_RANGE
110#define AP0_GAIN_BASE (int)(9830)
111#define AP0_GAIN_RANGE (int)(19660-9830)
112#define AP1_GAIN_BASE (int)(6553)
113#define AP1_GAIN_RANGE (int)(22936-6553)
114
115
116/* parameters for each allpass */
117typedef struct
118{
119 uint16_t m_zApOut; // delay offset for ap out
120
121 int16_t m_nApGain; // gain for ap
122
123 uint16_t m_zApIn; // delay offset for ap in
124
125} allpass_object_t;
126
127
128/* parameters for early reflections */
129typedef struct
130{
131 uint16_t m_zDelay[REVERB_MAX_NUM_REFLECTIONS]; // delay offset for ap out
132
133 int16_t m_nGain[REVERB_MAX_NUM_REFLECTIONS]; // gain for ap
134
135} early_reflection_object_t;
136
137//demo
138typedef struct
139{
140 int16_t m_nRvbLpfFbk;
141 int16_t m_nRvbLpfFwd;
142 int16_t m_nRoomLpfFbk;
143 int16_t m_nRoomLpfFwd;
144
145 int16_t m_nEarlyGain;
146 int16_t m_nEarlyDelay;
147 int16_t m_nLateGain;
148 int16_t m_nLateDelay;
149
150 early_reflection_object_t m_sEarlyL;
151 early_reflection_object_t m_sEarlyR;
152
153 uint16_t m_nMaxExcursion; //28
154 int16_t m_nXfadeInterval;
155
156 int16_t m_nAp0_ApGain; //30
157 int16_t m_nAp0_ApOut;
158 int16_t m_nAp1_ApGain;
159 int16_t m_nAp1_ApOut;
160 int16_t m_nDiffusion;
161
162 int16_t m_rfu4;
163 int16_t m_rfu5;
164 int16_t m_rfu6;
165 int16_t m_rfu7;
166 int16_t m_rfu8;
167 int16_t m_rfu9;
168 int16_t m_rfu10; //43
169
170} reverb_preset_t;
171
172typedef struct
173{
174 reverb_preset_t m_sPreset[REVERB_MAX_ROOM_TYPE]; //array of presets
175
176} reverb_preset_bank_t;
177
178
179/* parameters for each reverb */
180typedef struct
181{
182 /* update counter keeps track of when synth params need updating */
183 /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
184 int16_t m_nUpdateCounter;
185
186 uint16_t m_nBaseIndex; // base index for circular buffer
187
188 // reverb delay line offsets, allpass parameters, etc:
189
190 short m_nRevFbkR; // combine feedback reverb right out with dry left in
191 short m_zOutLpfL; // left reverb output
192
193 allpass_object_t m_sAp0; // allpass 0 (left channel)
194
195 uint16_t m_zD0In; // delay offset for delay line D0 in
196
197 short m_nRevFbkL; // combine feedback reverb left out with dry right in
198 short m_zOutLpfR; // right reverb output
199
200 allpass_object_t m_sAp1; // allpass 1 (right channel)
201
202 uint16_t m_zD1In; // delay offset for delay line D1 in
203
204 // delay output taps, notice criss cross order
205 uint16_t m_zD0Self; // self feeds forward d0 --> d0
206
207 uint16_t m_zD1Cross; // cross feeds across d1 --> d0
208
209 uint16_t m_zD1Self; // self feeds forward d1 --> d1
210
211 uint16_t m_zD0Cross; // cross feeds across d0 --> d1
212
213 int16_t m_nSin; // gain for self taps
214
215 int16_t m_nCos; // gain for cross taps
216
217 int16_t m_nSinIncrement; // increment for gain
218
219 int16_t m_nCosIncrement; // increment for gain
220
221 int16_t m_nRvbLpfFwd; // reverb feedback lpf forward gain (includes scaling for mixer)
222
223 int16_t m_nRvbLpfFbk; // reverb feedback lpf feedback gain
224
225 int16_t m_nRoomLpfFwd; // room lpf forward gain (includes scaling for mixer)
226
227 int16_t m_nRoomLpfFbk; // room lpf feedback gain
228
229 uint16_t m_nXfadeInterval; // update/xfade after this many samples
230
231 uint16_t m_nXfadeCounter; // keep track of when to xfade
232
233 int16_t m_nPhase; // -1 <= m_nPhase < 1
234 // but during sin,cos calculations
235 // use m_nPhase/2
236
237 int16_t m_nPhaseIncrement; // add this to m_nPhase each frame
238
239 int16_t m_nNoise; // random noise sample
240
241 uint16_t m_nMaxExcursion; // the taps can excurse +/- this amount
242
243 uint16_t m_bUseNoise; // if TRUE, use noise as input signal
244
245 uint16_t m_bBypass; // if TRUE, then bypass reverb and copy input to output
246
247 int16_t m_nCurrentRoom; // preset number for current room
248
249 int16_t m_nNextRoom; // preset number for next room
250
251 int16_t m_nEarlyGain; // gain for early (widen) signal
252 int16_t m_nEarlyDelay; // initial dealy for early (widen) signal
253 int16_t m_nEarly0in;
254 int16_t m_nEarly1in;
255 int16_t m_nLateGain; // gain for late reverb
256 int16_t m_nLateDelay;
257
258 int16_t m_nDiffusion;
259
260 early_reflection_object_t m_sEarlyL; // left channel early reflections
261 early_reflection_object_t m_sEarlyR; // right channel early reflections
262
263 short m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES_MAX]; // one large delay line for all reverb elements
264
265 reverb_preset_t pPreset;
266
267 reverb_preset_bank_t m_sPreset;
268
269 //int8_t preset;
270 uint32_t m_nSamplingRate;
271 int32_t m_nUpdatePeriodInBits;
272 int32_t m_nBufferMask;
273 int32_t m_nUpdatePeriodInSamples;
274 int32_t m_nDelay0Out;
275 int32_t m_nDelay1Out;
276 int16_t m_nCosWT_5KHz;
277
278 uint16_t m_Aux; // if TRUE, is connected as auxiliary effect
279 uint16_t m_Preset; // if TRUE, expose preset revert interface
280
281} reverb_object_t;
282
283
284
285typedef struct reverb_module_s {
286 const struct effect_interface_s *itfe;
287 effect_config_t config;
288 reverb_object_t context;
289} reverb_module_t;
290
291/*------------------------------------
292 * Effect API
293 *------------------------------------
294*/
295int EffectQueryNumberEffects(int *pNumEffects);
296int EffectQueryNext(effect_descriptor_t *pDescriptor);
297int EffectCreate(effect_uuid_t *effectUID, effect_interface_t *pInterface);
298int EffectRelease(effect_interface_t interface);
299
300static int Reverb_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer);
301static int Reverb_Command(effect_interface_t self, int cmdCode, int cmdSize, void *pCmdData, int *replySize, void *pReplyData);
302
303
304/*------------------------------------
305 * internal functions
306 *------------------------------------
307*/
308
309int Reverb_Init(reverb_module_t *pRvbModule, int aux, int preset);
310int Reverb_Configure(reverb_module_t *pRvbModule, effect_config_t *pConfig, bool init);
311void Reverb_Reset(reverb_object_t *pReverb, bool init);
312
313int Reverb_setParameter (reverb_object_t *pReverb, int32_t param, size_t size, void *pValue);
314int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize, void *pValue);
315
316/*----------------------------------------------------------------------------
317 * ReverbUpdateXfade
318 *----------------------------------------------------------------------------
319 * Purpose:
320 * Update the xfade parameters as required
321 *
322 * Inputs:
323 * nNumSamplesToAdd - number of samples to write to buffer
324 *
325 * Outputs:
326 *
327 *
328 * Side Effects:
329 * - xfade parameters will be changed
330 *
331 *----------------------------------------------------------------------------
332*/
333static int ReverbUpdateXfade(reverb_object_t* pReverbData, int nNumSamplesToAdd);
334
335/*----------------------------------------------------------------------------
336 * ReverbCalculateNoise
337 *----------------------------------------------------------------------------
338 * Purpose:
339 * Calculate a noise sample and limit its value
340 *
341 * Inputs:
342 * Pointer to reverb context
343 *
344 * Outputs:
345 * new limited noise value
346 *
347 * Side Effects:
348 * - pReverbData->m_nNoise value is updated
349 *
350 *----------------------------------------------------------------------------
351*/
352static uint16_t ReverbCalculateNoise(reverb_object_t *pReverbData);
353
354/*----------------------------------------------------------------------------
355 * ReverbCalculateSinCos
356 *----------------------------------------------------------------------------
357 * Purpose:
358 * Calculate a new sin and cosine value based on the given phase
359 *
360 * Inputs:
361 * nPhase - phase angle
362 * pnSin - input old value, output new value
363 * pnCos - input old value, output new value
364 *
365 * Outputs:
366 *
367 * Side Effects:
368 * - *pnSin, *pnCos are updated
369 *
370 *----------------------------------------------------------------------------
371*/
372static int ReverbCalculateSinCos(int16_t nPhase, int16_t *pnSin, int16_t *pnCos);
373
374/*----------------------------------------------------------------------------
375 * Reverb
376 *----------------------------------------------------------------------------
377 * Purpose:
378 * apply reverb to the given signal
379 *
380 * Inputs:
381 * nNu
382 * pnSin - input old value, output new value
383 * pnCos - input old value, output new value
384 *
385 * Outputs:
386 * number of samples actually reverberated
387 *
388 * Side Effects:
389 *
390 *----------------------------------------------------------------------------
391*/
392static int Reverb(reverb_object_t* pReverbData, int nNumSamplesToAdd, short *pOutputBuffer, short *pInputBuffer);
393
394/*----------------------------------------------------------------------------
395 * ReverbReadInPresets()
396 *----------------------------------------------------------------------------
397 * Purpose: sets global reverb preset bank to defaults
398 *
399 * Inputs:
400 *
401 * Outputs:
402 *
403 *----------------------------------------------------------------------------
404*/
405static int ReverbReadInPresets(reverb_object_t* pReverbData);
406
407
408/*----------------------------------------------------------------------------
409 * ReverbUpdateRoom
410 *----------------------------------------------------------------------------
411 * Purpose:
412 * Update the room's preset parameters as required
413 *
414 * Inputs:
415 *
416 * Outputs:
417 *
418 *
419 * Side Effects:
420 * - reverb paramters (fbk, fwd, etc) will be changed
421 * - m_nCurrentRoom := m_nNextRoom
422 *----------------------------------------------------------------------------
423*/
424static int ReverbUpdateRoom(reverb_object_t* pReverbData, bool fullUpdate);
425
426
427static int ReverbComputeConstants(reverb_object_t *pReverbData, uint32_t samplingRate);
428
429#endif /*ANDROID_EFFECTREVERB_H_*/