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