Home | History | Annotate | Download | only in lib_src
      1 /*----------------------------------------------------------------------------
      2  *
      3  * File:
      4  * eas_reverbdata.h
      5  *
      6  * Contents and purpose:
      7  * Contains the prototypes for the Reverb effect.
      8  *
      9  *
     10  * Copyright Sonic Network Inc. 2006
     11 
     12  * Licensed under the Apache License, Version 2.0 (the "License");
     13  * you may not use this file except in compliance with the License.
     14  * You may obtain a copy of the License at
     15  *
     16  *      http://www.apache.org/licenses/LICENSE-2.0
     17  *
     18  * Unless required by applicable law or agreed to in writing, software
     19  * distributed under the License is distributed on an "AS IS" BASIS,
     20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     21  * See the License for the specific language governing permissions and
     22  * limitations under the License.
     23  *
     24  *----------------------------------------------------------------------------
     25  * Revision Control:
     26  *   $Revision: 499 $
     27  *   $Date: 2006-12-11 16:07:20 -0800 (Mon, 11 Dec 2006) $
     28  *----------------------------------------------------------------------------
     29 */
     30 
     31 #ifndef _EAS_REVERBDATA_H
     32 #define _EAS_REVERBDATA_H
     33 
     34 #include "eas_types.h"
     35 #include "eas_audioconst.h"
     36 
     37 /*------------------------------------
     38  * defines
     39  *------------------------------------
     40 */
     41 
     42 /*
     43 CIRCULAR() calculates the array index using modulo arithmetic.
     44 The "trick" is that modulo arithmetic is simplified by masking
     45 the effective address where the mask is (2^n)-1. This only works
     46 if the buffer size is a power of two.
     47 */
     48 #define CIRCULAR(base,offset,size) (EAS_U32)(               \
     49             (                                               \
     50                 ((EAS_I32)(base)) + ((EAS_I32)(offset))     \
     51             )                                               \
     52             & size                                          \
     53                                             )
     54 
     55 /* reverb parameters are updated every 2^(REVERB_UPDATE_PERIOD_IN_BITS) samples */
     56 #if defined (_SAMPLE_RATE_8000)
     57 
     58 #define REVERB_UPDATE_PERIOD_IN_BITS        5
     59 #define REVERB_BUFFER_SIZE_IN_SAMPLES       2048
     60 
     61 #elif defined (_SAMPLE_RATE_16000)
     62 
     63 #define REVERB_UPDATE_PERIOD_IN_BITS        6
     64 #define REVERB_BUFFER_SIZE_IN_SAMPLES       4096
     65 
     66 #elif defined (_SAMPLE_RATE_22050)
     67 
     68 #define REVERB_UPDATE_PERIOD_IN_BITS        7
     69 #define REVERB_BUFFER_SIZE_IN_SAMPLES       4096
     70 
     71 #elif defined (_SAMPLE_RATE_32000)
     72 
     73 #define REVERB_UPDATE_PERIOD_IN_BITS        7
     74 #define REVERB_BUFFER_SIZE_IN_SAMPLES       8192
     75 
     76 #elif defined (_SAMPLE_RATE_44100)
     77 
     78 #define REVERB_UPDATE_PERIOD_IN_BITS        8
     79 #define REVERB_BUFFER_SIZE_IN_SAMPLES       8192
     80 
     81 #elif defined (_SAMPLE_RATE_48000)
     82 
     83 #define REVERB_UPDATE_PERIOD_IN_BITS        8
     84 #define REVERB_BUFFER_SIZE_IN_SAMPLES       8192
     85 
     86 #endif
     87 
     88 // Define a mask for circular addressing, so that array index
     89 // can wraparound and stay in array boundary of 0, 1, ..., (buffer size -1)
     90 // The buffer size MUST be a power of two
     91 #define REVERB_BUFFER_MASK                  (REVERB_BUFFER_SIZE_IN_SAMPLES -1)
     92 
     93 #define REVERB_MAX_ROOM_TYPE            4   // any room numbers larger than this are invalid
     94 #define REVERB_MAX_NUM_REFLECTIONS      5   // max num reflections per channel
     95 
     96 /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
     97 #define REVERB_UPDATE_PERIOD_IN_SAMPLES (EAS_I32)(0x1L << REVERB_UPDATE_PERIOD_IN_BITS)
     98 
     99 /*
    100 calculate the update counter by bitwise ANDING with this value to
    101 generate a 2^n modulo value
    102 */
    103 #define REVERB_MODULO_UPDATE_PERIOD_IN_SAMPLES  (EAS_I32)(REVERB_UPDATE_PERIOD_IN_SAMPLES -1)
    104 
    105 /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SECONDS seconds */
    106 #define REVERB_UPDATE_PERIOD_IN_SECONDS     (REVERB_UPDATE_PERIOD_IN_SAMPLES / _OUTPUT_SAMPLE_RATE)
    107 
    108 // xfade parameters
    109 #define REVERB_XFADE_PERIOD_IN_SECONDS      (100.0 / 1000.0)        // xfade once every this many seconds
    110 
    111 #define REVERB_XFADE_PERIOD_IN_SAMPLES      (REVERB_XFADE_PERIOD_IN_SECONDS * _OUTPUT_SAMPLE_RATE)
    112 
    113 #define REVERB_XFADE_PHASE_INCREMENT    (EAS_I16)(65536 / ((EAS_I16)REVERB_XFADE_PERIOD_IN_SAMPLES/(EAS_I16)REVERB_UPDATE_PERIOD_IN_SAMPLES))
    114 
    115 /**********/
    116 /* the entire synth uses various flags in a bit field */
    117 
    118 /* if flag is set, synth reset has been requested */
    119 #define REVERB_FLAG_RESET_IS_REQUESTED          0x01    /* bit 0 */
    120 #define MASK_REVERB_RESET_IS_REQUESTED          0x01
    121 #define MASK_REVERB_RESET_IS_NOT_REQUESTED      (EAS_U32)(~MASK_REVERB_RESET_IS_REQUESTED)
    122 
    123 /*
    124 by default, we always want to update ALL channel parameters
    125 when we reset the synth (e.g., during GM ON)
    126 */
    127 #define DEFAULT_REVERB_FLAGS                    0x0
    128 
    129 /* coefficients for generating sin, cos */
    130 #define REVERB_PAN_G2   4294940151          /* -0.82842712474619 = 2 - 4/sqrt(2) */
    131 /*
    132 EAS_I32 nPanG1 = +1.0 for sin
    133 EAS_I32 nPanG1 = -1.0 for cos
    134 */
    135 #define REVERB_PAN_G0   23170               /* 0.707106781186547 = 1/sqrt(2) */
    136 
    137 /*************************************************************/
    138 // define the input injection points
    139 #define GUARD               5                       // safety guard of this many samples
    140 
    141 #define MAX_AP_TIME         (double) (20.0/1000.0)  // delay time in milliseconds
    142 #define MAX_DELAY_TIME      (double) (65.0/1000.0)  // delay time in milliseconds
    143 
    144 #define MAX_AP_SAMPLES      (int)(((double) MAX_AP_TIME)    * ((double) _OUTPUT_SAMPLE_RATE))
    145 #define MAX_DELAY_SAMPLES   (int)(((double) MAX_DELAY_TIME) * ((double) _OUTPUT_SAMPLE_RATE))
    146 
    147 #define AP0_IN              0
    148 #define AP1_IN              (AP0_IN     + MAX_AP_SAMPLES    + GUARD)
    149 #define DELAY0_IN           (AP1_IN     + MAX_AP_SAMPLES    + GUARD)
    150 #define DELAY1_IN           (DELAY0_IN  + MAX_DELAY_SAMPLES + GUARD)
    151 
    152 // Define the max offsets for the end points of each section
    153 // i.e., we don't expect a given section's taps to go beyond
    154 // the following limits
    155 #define AP0_OUT             (AP0_IN     + MAX_AP_SAMPLES    -1)
    156 #define AP1_OUT             (AP1_IN     + MAX_AP_SAMPLES    -1)
    157 #define DELAY0_OUT          (DELAY0_IN  + MAX_DELAY_SAMPLES -1)
    158 #define DELAY1_OUT          (DELAY1_IN  + MAX_DELAY_SAMPLES -1)
    159 
    160 #define REVERB_DEFAULT_ROOM_NUMBER      1       // default preset number
    161 #define DEFAULT_AP0_LENGTH              (int)(((double) (17.0/1000.0))  * ((double) _OUTPUT_SAMPLE_RATE))
    162 #define DEFAULT_AP0_GAIN                19400
    163 #define DEFAULT_AP1_LENGTH              (int)(((double) (16.5/1000.0))  * ((double) _OUTPUT_SAMPLE_RATE))
    164 #define DEFAULT_AP1_GAIN                -19400
    165 
    166 #define REVERB_DEFAULT_WET              32767
    167 #define REVERB_DEFAULT_DRY              0
    168 
    169 #define EAS_REVERB_WET_MAX              32767
    170 #define EAS_REVERB_WET_MIN              0
    171 #define EAS_REVERB_DRY_MAX              32767
    172 #define EAS_REVERB_DRY_MIN              0
    173 
    174 /* parameters for each allpass */
    175 typedef struct
    176 {
    177     EAS_U16             m_zApOut;       // delay offset for ap out
    178 
    179     EAS_I16             m_nApGain;      // gain for ap
    180 
    181     EAS_U16             m_zApIn;        // delay offset for ap in
    182 
    183 } S_ALLPASS_OBJECT;
    184 
    185 
    186 /* parameters for each allpass */
    187 typedef struct
    188 {
    189     EAS_PCM             m_zLpf;                     // actual state variable, not a length
    190 
    191     EAS_I16             m_nLpfFwd;                  // lpf forward gain
    192 
    193     EAS_I16             m_nLpfFbk;                  // lpf feedback gain
    194 
    195     EAS_U16             m_zDelay[REVERB_MAX_NUM_REFLECTIONS];   // delay offset for ap out
    196 
    197     EAS_I16             m_nGain[REVERB_MAX_NUM_REFLECTIONS];    // gain for ap
    198 
    199 } S_EARLY_REFLECTION_OBJECT;
    200 
    201 //demo
    202 typedef struct
    203 {
    204     EAS_I16             m_nLpfFbk;
    205     EAS_I16             m_nLpfFwd;
    206 
    207     EAS_I16             m_nEarly;
    208     EAS_I16             m_nWet;
    209     EAS_I16             m_nDry;
    210 
    211     EAS_I16             m_nEarlyL_LpfFbk;
    212     EAS_I16             m_nEarlyL_LpfFwd;
    213 
    214     EAS_I16             m_nEarlyL_Delay0; //8
    215     EAS_I16             m_nEarlyL_Gain0;
    216     EAS_I16             m_nEarlyL_Delay1;
    217     EAS_I16             m_nEarlyL_Gain1;
    218     EAS_I16             m_nEarlyL_Delay2;
    219     EAS_I16             m_nEarlyL_Gain2;
    220     EAS_I16             m_nEarlyL_Delay3;
    221     EAS_I16             m_nEarlyL_Gain3;
    222     EAS_I16             m_nEarlyL_Delay4;
    223     EAS_I16             m_nEarlyL_Gain4;
    224 
    225     EAS_I16             m_nEarlyR_Delay0; //18
    226     EAS_I16             m_nEarlyR_Gain0;
    227     EAS_I16             m_nEarlyR_Delay1;
    228     EAS_I16             m_nEarlyR_Gain1;
    229     EAS_I16             m_nEarlyR_Delay2;
    230     EAS_I16             m_nEarlyR_Gain2;
    231     EAS_I16             m_nEarlyR_Delay3;
    232     EAS_I16             m_nEarlyR_Gain3;
    233     EAS_I16             m_nEarlyR_Delay4;
    234     EAS_I16             m_nEarlyR_Gain4;
    235 
    236     EAS_U16             m_nMaxExcursion; //28
    237     EAS_I16             m_nXfadeInterval;
    238 
    239     EAS_I16             m_nAp0_ApGain; //30
    240     EAS_I16             m_nAp0_ApOut;
    241     EAS_I16             m_nAp1_ApGain;
    242     EAS_I16             m_nAp1_ApOut;
    243 
    244     EAS_I16             m_rfu4;
    245     EAS_I16             m_rfu5;
    246     EAS_I16             m_rfu6;
    247     EAS_I16             m_rfu7;
    248     EAS_I16             m_rfu8;
    249     EAS_I16             m_rfu9;
    250     EAS_I16             m_rfu10; //43
    251 
    252 } S_REVERB_PRESET;
    253 
    254 typedef struct
    255 {
    256     S_REVERB_PRESET     m_sPreset[REVERB_MAX_ROOM_TYPE];    //array of presets
    257 
    258 } S_REVERB_PRESET_BANK;
    259 
    260 /* parameters for each reverb */
    261 typedef struct
    262 {
    263     /* controls entire reverb playback volume */
    264     /* to conserve memory, use the MSB and ignore the LSB */
    265     EAS_U8              m_nMasterVolume;
    266 
    267     /* update counter keeps track of when synth params need updating */
    268     /* only needs to be as large as REVERB_UPDATE_PERIOD_IN_SAMPLES */
    269     EAS_I16             m_nUpdateCounter;
    270 
    271     EAS_U16             m_nMinSamplesToAdd;         /* ComputeReverb() generates this many samples */
    272 
    273     EAS_U8              m_nFlags;                   /* misc flags/bit fields */
    274 
    275     EAS_PCM             *m_pOutputBuffer;
    276     EAS_PCM             *m_pInputBuffer;
    277 
    278     EAS_U16             m_nNumSamplesInOutputBuffer;
    279     EAS_U16             m_nNumSamplesInInputBuffer;
    280 
    281     EAS_U16             m_nNumInputSamplesRead;     // if m_nNumInputSamplesRead >= NumSamplesInInputBuffer
    282                                                     // then get a new input buffer
    283     EAS_PCM             *m_pNextInputSample;
    284 
    285     EAS_U16             m_nBaseIndex;                                   // base index for circular buffer
    286 
    287     // reverb delay line offsets, allpass parameters, etc:
    288 
    289     EAS_PCM             m_nRevOutFbkR;              // combine feedback reverb right out with dry left in
    290 
    291     S_ALLPASS_OBJECT    m_sAp0;                     // allpass 0 (left channel)
    292 
    293     EAS_U16             m_zD0In;                    // delay offset for delay line D0 in
    294 
    295     EAS_PCM             m_nRevOutFbkL;              // combine feedback reverb left out with dry right in
    296 
    297     S_ALLPASS_OBJECT    m_sAp1;                     // allpass 1 (right channel)
    298 
    299     EAS_U16             m_zD1In;                    // delay offset for delay line D1 in
    300 
    301     // delay output taps, notice criss cross order
    302     EAS_U16             m_zD0Self;                  // self feeds forward d0 --> d0
    303 
    304     EAS_U16             m_zD1Cross;                 // cross feeds across d1 --> d0
    305 
    306     EAS_PCM             m_zLpf0;                    // actual state variable, not a length
    307 
    308     EAS_U16             m_zD1Self;                  // self feeds forward d1 --> d1
    309 
    310     EAS_U16             m_zD0Cross;                 // cross feeds across d0 --> d1
    311 
    312     EAS_PCM             m_zLpf1;                    // actual state variable, not a length
    313 
    314     EAS_I16             m_nSin;                     // gain for self taps
    315 
    316     EAS_I16             m_nCos;                     // gain for cross taps
    317 
    318     EAS_I16             m_nSinIncrement;            // increment for gain
    319 
    320     EAS_I16             m_nCosIncrement;            // increment for gain
    321 
    322     EAS_I16             m_nLpfFwd;                  // lpf forward gain (includes scaling for mixer)
    323 
    324     EAS_I16             m_nLpfFbk;                  // lpf feedback gain
    325 
    326     EAS_U16             m_nXfadeInterval;           // update/xfade after this many samples
    327 
    328     EAS_U16             m_nXfadeCounter;            // keep track of when to xfade
    329 
    330     EAS_I16             m_nPhase;                   // -1 <= m_nPhase < 1
    331                                                     // but during sin,cos calculations
    332                                                     // use m_nPhase/2
    333 
    334     EAS_I16             m_nPhaseIncrement;          // add this to m_nPhase each frame
    335 
    336     EAS_I16             m_nNoise;                   // random noise sample
    337 
    338     EAS_U16             m_nMaxExcursion;            // the taps can excurse +/- this amount
    339 
    340     EAS_BOOL            m_bUseNoise;                // if EAS_TRUE, use noise as input signal
    341 
    342     EAS_BOOL            m_bBypass;                  // if EAS_TRUE, then bypass reverb and copy input to output
    343 
    344     EAS_I16             m_nCurrentRoom;             // preset number for current room
    345 
    346     EAS_I16             m_nNextRoom;                // preset number for next room
    347 
    348     EAS_I16             m_nWet;                     // gain for wet (processed) signal
    349 
    350     EAS_I16             m_nDry;                     // gain for dry (unprocessed) signal
    351 
    352     EAS_I16             m_nEarly;                   // gain for early (widen) signal
    353 
    354     S_EARLY_REFLECTION_OBJECT   m_sEarlyL;          // left channel early reflections
    355     S_EARLY_REFLECTION_OBJECT   m_sEarlyR;          // right channel early reflections
    356 
    357     EAS_PCM             m_nDelayLine[REVERB_BUFFER_SIZE_IN_SAMPLES];    // one large delay line for all reverb elements
    358 
    359     S_REVERB_PRESET     pPreset;
    360 
    361     S_REVERB_PRESET_BANK    m_sPreset;
    362 
    363     //EAS_I8            preset;
    364 
    365 } S_REVERB_OBJECT;
    366 
    367 
    368 /*------------------------------------
    369  * prototypes
    370  *------------------------------------
    371 */
    372 
    373 /*----------------------------------------------------------------------------
    374  * ReverbUpdateXfade
    375  *----------------------------------------------------------------------------
    376  * Purpose:
    377  * Update the xfade parameters as required
    378  *
    379  * Inputs:
    380  * nNumSamplesToAdd - number of samples to write to buffer
    381  *
    382  * Outputs:
    383  *
    384  *
    385  * Side Effects:
    386  * - xfade parameters will be changed
    387  *
    388  *----------------------------------------------------------------------------
    389 */
    390 static EAS_RESULT ReverbUpdateXfade(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd);
    391 
    392 /*----------------------------------------------------------------------------
    393  * ReverbCalculateNoise
    394  *----------------------------------------------------------------------------
    395  * Purpose:
    396  * Calculate a noise sample and limit its value
    397  *
    398  * Inputs:
    399  * nMaxExcursion - noise value is limited to this value
    400  * pnNoise - return new noise sample in this (not limited)
    401  *
    402  * Outputs:
    403  * new limited noise value
    404  *
    405  * Side Effects:
    406  * - *pnNoise noise value is updated
    407  *
    408  *----------------------------------------------------------------------------
    409 */
    410 static EAS_U16 ReverbCalculateNoise(EAS_U16 nMaxExcursion, EAS_I16 *pnNoise);
    411 
    412 /*----------------------------------------------------------------------------
    413  * ReverbCalculateSinCos
    414  *----------------------------------------------------------------------------
    415  * Purpose:
    416  * Calculate a new sin and cosine value based on the given phase
    417  *
    418  * Inputs:
    419  * nPhase   - phase angle
    420  * pnSin    - input old value, output new value
    421  * pnCos    - input old value, output new value
    422  *
    423  * Outputs:
    424  *
    425  * Side Effects:
    426  * - *pnSin, *pnCos are updated
    427  *
    428  *----------------------------------------------------------------------------
    429 */
    430 static EAS_RESULT ReverbCalculateSinCos(EAS_I16 nPhase, EAS_I16 *pnSin, EAS_I16 *pnCos);
    431 
    432 /*----------------------------------------------------------------------------
    433  * Reverb
    434  *----------------------------------------------------------------------------
    435  * Purpose:
    436  * apply reverb to the given signal
    437  *
    438  * Inputs:
    439  * nNu
    440  * pnSin    - input old value, output new value
    441  * pnCos    - input old value, output new value
    442  *
    443  * Outputs:
    444  * number of samples actually reverberated
    445  *
    446  * Side Effects:
    447  *
    448  *----------------------------------------------------------------------------
    449 */
    450 static EAS_RESULT Reverb(S_REVERB_OBJECT* pReverbData, EAS_INT nNumSamplesToAdd, EAS_PCM *pOutputBuffer, EAS_PCM *pInputBuffer);
    451 
    452 /*----------------------------------------------------------------------------
    453  * ReverbReadInPresets()
    454  *----------------------------------------------------------------------------
    455  * Purpose: sets global reverb preset bank to defaults
    456  *
    457  * Inputs:
    458  *
    459  * Outputs:
    460  *
    461  *----------------------------------------------------------------------------
    462 */
    463 static EAS_RESULT ReverbReadInPresets(S_REVERB_OBJECT* pReverbData);
    464 
    465 
    466 /*----------------------------------------------------------------------------
    467  * ReverbUpdateRoom
    468  *----------------------------------------------------------------------------
    469  * Purpose:
    470  * Update the room's preset parameters as required
    471  *
    472  * Inputs:
    473  *
    474  * Outputs:
    475  *
    476  *
    477  * Side Effects:
    478  * - reverb paramters (fbk, fwd, etc) will be changed
    479  * - m_nCurrentRoom := m_nNextRoom
    480  *----------------------------------------------------------------------------
    481 */
    482 static EAS_RESULT ReverbUpdateRoom(S_REVERB_OBJECT* pReverbData);
    483 
    484 #endif /* #ifndef _EAS_REVERBDATA_H */
    485 
    486 
    487