1/*
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 <audio_effects/effect_environmentalreverb.h>
21#include <audio_effects/effect_presetreverb.h>
22
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
43#define OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO
44
45#define REVERB_BUFFER_SIZE_IN_SAMPLES_MAX   16384
46
47#define REVERB_NUM_PRESETS  REVERB_PRESET_PLATE   // REVERB_PRESET_NONE is not included
48#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
117enum reverb_state_e {
118    REVERB_STATE_UNINITIALIZED,
119    REVERB_STATE_INITIALIZED,
120    REVERB_STATE_ACTIVE,
121};
122
123/* 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{
181    reverb_preset_t     m_sPreset[REVERB_NUM_PRESETS]; // array of presets(does not include REVERB_PRESET_NONE)
182
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
288    uint32_t            mState;
289} 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*/
303int EffectQueryNumberEffects(uint32_t *pNumEffects);
304int EffectQueryEffect(uint32_t index,
305                      effect_descriptor_t *pDescriptor);
306int EffectCreate(const effect_uuid_t *effectUID,
307                 int32_t sessionId,
308                 int32_t ioId,
309                 effect_handle_t *pHandle);
310int EffectRelease(effect_handle_t handle);
311int EffectGetDescriptor(const effect_uuid_t *uuid,
312                        effect_descriptor_t *pDescriptor);
313
314static int Reverb_Process(effect_handle_t self,
315                          audio_buffer_t *inBuffer,
316                          audio_buffer_t *outBuffer);
317static int Reverb_Command(effect_handle_t self,
318                          uint32_t cmdCode,
319                          uint32_t cmdSize,
320                          void *pCmdData,
321                          uint32_t *replySize,
322                          void *pReplyData);
323static int Reverb_GetDescriptor(effect_handle_t   self,
324                                effect_descriptor_t *pDescriptor);
325
326/*------------------------------------
327 * internal functions
328 *------------------------------------
329*/
330
331int Reverb_Init(reverb_module_t *pRvbModule, int aux, int preset);
332int Reverb_setConfig(reverb_module_t *pRvbModule, effect_config_t *pConfig, bool init);
333void Reverb_getConfig(reverb_module_t *pRvbModule, effect_config_t *pConfig);
334void Reverb_Reset(reverb_object_t *pReverb, bool init);
335
336int Reverb_setParameter (reverb_object_t *pReverb, int32_t param, size_t size, void *pValue);
337int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize, void *pValue);
338
339/*----------------------------------------------------------------------------
340 * ReverbUpdateXfade
341 *----------------------------------------------------------------------------
342 * Purpose:
343 * Update the xfade parameters as required
344 *
345 * Inputs:
346 * nNumSamplesToAdd - number of samples to write to buffer
347 *
348 * Outputs:
349 *
350 *
351 * Side Effects:
352 * - xfade parameters will be changed
353 *
354 *----------------------------------------------------------------------------
355*/
356static int ReverbUpdateXfade(reverb_object_t* pReverbData, int nNumSamplesToAdd);
357
358/*----------------------------------------------------------------------------
359 * ReverbCalculateNoise
360 *----------------------------------------------------------------------------
361 * Purpose:
362 * Calculate a noise sample and limit its value
363 *
364 * Inputs:
365 * Pointer to reverb context
366 *
367 * Outputs:
368 * new limited noise value
369 *
370 * Side Effects:
371 * - pReverbData->m_nNoise value is updated
372 *
373 *----------------------------------------------------------------------------
374*/
375static uint16_t ReverbCalculateNoise(reverb_object_t *pReverbData);
376
377/*----------------------------------------------------------------------------
378 * ReverbCalculateSinCos
379 *----------------------------------------------------------------------------
380 * Purpose:
381 * Calculate a new sin and cosine value based on the given phase
382 *
383 * Inputs:
384 * nPhase   - phase angle
385 * pnSin    - input old value, output new value
386 * pnCos    - input old value, output new value
387 *
388 * Outputs:
389 *
390 * Side Effects:
391 * - *pnSin, *pnCos are updated
392 *
393 *----------------------------------------------------------------------------
394*/
395static int ReverbCalculateSinCos(int16_t nPhase, int16_t *pnSin, int16_t *pnCos);
396
397/*----------------------------------------------------------------------------
398 * Reverb
399 *----------------------------------------------------------------------------
400 * Purpose:
401 * apply reverb to the given signal
402 *
403 * Inputs:
404 * nNu
405 * pnSin    - input old value, output new value
406 * pnCos    - input old value, output new value
407 *
408 * Outputs:
409 * number of samples actually reverberated
410 *
411 * Side Effects:
412 *
413 *----------------------------------------------------------------------------
414*/
415static int Reverb(reverb_object_t* pReverbData, int nNumSamplesToAdd, short *pOutputBuffer, short *pInputBuffer);
416
417/*----------------------------------------------------------------------------
418 * ReverbReadInPresets()
419 *----------------------------------------------------------------------------
420 * Purpose: sets global reverb preset bank to defaults
421 *
422 * Inputs:
423 *
424 * Outputs:
425 *
426 *----------------------------------------------------------------------------
427*/
428static int ReverbReadInPresets(reverb_object_t* pReverbData);
429
430
431/*----------------------------------------------------------------------------
432 * ReverbUpdateRoom
433 *----------------------------------------------------------------------------
434 * Purpose:
435 * Update the room's preset parameters as required
436 *
437 * Inputs:
438 *
439 * Outputs:
440 *
441 *
442 * Side Effects:
443 * - reverb paramters (fbk, fwd, etc) will be changed
444 * - m_nCurrentRoom := m_nNextRoom
445 *----------------------------------------------------------------------------
446*/
447static int ReverbUpdateRoom(reverb_object_t* pReverbData, bool fullUpdate);
448
449
450static int ReverbComputeConstants(reverb_object_t *pReverbData, uint32_t samplingRate);
451
452#endif /*ANDROID_EFFECTREVERB_H_*/
453