1 /* 2 * Copyright (C) 2004-2010 NXP Software 3 * Copyright (C) 2010 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 19 /****************************************************************************************/ 20 /* */ 21 /* Includes */ 22 /* */ 23 /****************************************************************************************/ 24 25 #include "VectorArithmetic.h" 26 #include "ScalarArithmetic.h" 27 #include "LVM_Coeffs.h" 28 #include "LVM_Tables.h" 29 #include "LVM_Private.h" 30 31 /****************************************************************************************/ 32 /* */ 33 /* FUNCTION: LVM_SetControlParameters */ 34 /* */ 35 /* DESCRIPTION: */ 36 /* Sets or changes the LifeVibes module parameters. */ 37 /* */ 38 /* PARAMETERS: */ 39 /* hInstance Instance handle */ 40 /* pParams Pointer to a parameter structure */ 41 /* */ 42 /* RETURNS: */ 43 /* LVM_SUCCESS Succeeded */ 44 /* LVM_NULLADDRESS When hInstance, pParams or any control pointers are NULL */ 45 /* LVM_OUTOFRANGE When any of the control parameters are out of range */ 46 /* */ 47 /* NOTES: */ 48 /* 1. This function may be interrupted by the LVM_Process function */ 49 /* */ 50 /****************************************************************************************/ 51 52 LVM_ReturnStatus_en LVM_SetControlParameters(LVM_Handle_t hInstance, 53 LVM_ControlParams_t *pParams) 54 { 55 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 56 57 58 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL)) 59 { 60 return (LVM_NULLADDRESS); 61 } 62 63 pInstance->NewParams = *pParams; 64 65 if( 66 /* General parameters */ 67 ((pParams->OperatingMode != LVM_MODE_OFF) && (pParams->OperatingMode != LVM_MODE_ON)) || 68 ((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) && 69 (pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) && 70 (pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000)) || 71 ((pParams->SourceFormat != LVM_STEREO) && (pParams->SourceFormat != LVM_MONOINSTEREO) && (pParams->SourceFormat != LVM_MONO)) || 72 (pParams->SpeakerType > LVM_EX_HEADPHONES)) 73 { 74 return (LVM_OUTOFRANGE); 75 } 76 77 /* 78 * Cinema Sound parameters 79 */ 80 if((pParams->VirtualizerOperatingMode != LVM_MODE_OFF) && (pParams->VirtualizerOperatingMode != LVM_MODE_ON)) 81 { 82 return (LVM_OUTOFRANGE); 83 } 84 85 if(pParams->VirtualizerType != LVM_CONCERTSOUND) 86 { 87 return (LVM_OUTOFRANGE); 88 } 89 90 if(pParams->VirtualizerReverbLevel > LVM_VIRTUALIZER_MAX_REVERB_LEVEL) 91 { 92 return (LVM_OUTOFRANGE); 93 } 94 95 if(pParams->CS_EffectLevel < LVM_CS_MIN_EFFECT_LEVEL) 96 { 97 return (LVM_OUTOFRANGE); 98 } 99 100 /* 101 * N-Band Equalizer 102 */ 103 if(pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands) 104 { 105 return (LVM_OUTOFRANGE); 106 } 107 108 /* Definition pointer */ 109 if ((pParams->pEQNB_BandDefinition == LVM_NULL) && 110 (pParams->EQNB_NBands != 0)) 111 { 112 return (LVM_NULLADDRESS); 113 } 114 115 /* 116 * Copy the filter definitions for the Equaliser 117 */ 118 { 119 LVM_INT16 i; 120 121 if (pParams->EQNB_NBands != 0) 122 { 123 for (i=0; i<pParams->EQNB_NBands; i++) 124 { 125 pInstance->pEQNB_BandDefs[i] = pParams->pEQNB_BandDefinition[i]; 126 } 127 pInstance->NewParams.pEQNB_BandDefinition = pInstance->pEQNB_BandDefs; 128 } 129 } 130 if( /* N-Band Equaliser parameters */ 131 ((pParams->EQNB_OperatingMode != LVM_EQNB_OFF) && (pParams->EQNB_OperatingMode != LVM_EQNB_ON)) || 132 (pParams->EQNB_NBands > pInstance->InstParams.EQNB_NumBands)) 133 { 134 return (LVM_OUTOFRANGE); 135 } 136 /* Band parameters*/ 137 { 138 LVM_INT16 i; 139 for(i = 0; i < pParams->EQNB_NBands; i++) 140 { 141 if(((pParams->pEQNB_BandDefinition[i].Frequency < LVM_EQNB_MIN_BAND_FREQ) || 142 (pParams->pEQNB_BandDefinition[i].Frequency > LVM_EQNB_MAX_BAND_FREQ)) || 143 ((pParams->pEQNB_BandDefinition[i].Gain < LVM_EQNB_MIN_BAND_GAIN) || 144 (pParams->pEQNB_BandDefinition[i].Gain > LVM_EQNB_MAX_BAND_GAIN)) || 145 ((pParams->pEQNB_BandDefinition[i].QFactor < LVM_EQNB_MIN_QFACTOR) || 146 (pParams->pEQNB_BandDefinition[i].QFactor > LVM_EQNB_MAX_QFACTOR))) 147 { 148 return (LVM_OUTOFRANGE); 149 } 150 } 151 } 152 153 /* 154 * Bass Enhancement parameters 155 */ 156 if(((pParams->BE_OperatingMode != LVM_BE_OFF) && (pParams->BE_OperatingMode != LVM_BE_ON)) || 157 ((pParams->BE_EffectLevel < LVM_BE_MIN_EFFECTLEVEL ) || (pParams->BE_EffectLevel > LVM_BE_MAX_EFFECTLEVEL ))|| 158 ((pParams->BE_CentreFreq != LVM_BE_CENTRE_55Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_66Hz) && 159 (pParams->BE_CentreFreq != LVM_BE_CENTRE_78Hz) && (pParams->BE_CentreFreq != LVM_BE_CENTRE_90Hz)) || 160 ((pParams->BE_HPF != LVM_BE_HPF_OFF) && (pParams->BE_HPF != LVM_BE_HPF_ON))) 161 { 162 return (LVM_OUTOFRANGE); 163 } 164 165 /* 166 * Volume Control parameters 167 */ 168 if((pParams->VC_EffectLevel < LVM_VC_MIN_EFFECTLEVEL ) || (pParams->VC_EffectLevel > LVM_VC_MAX_EFFECTLEVEL )) 169 { 170 return (LVM_OUTOFRANGE); 171 } 172 if((pParams->VC_Balance < LVM_VC_BALANCE_MIN ) || (pParams->VC_Balance > LVM_VC_BALANCE_MAX )) 173 { 174 return (LVM_OUTOFRANGE); 175 } 176 177 /* 178 * PSA parameters 179 */ 180 if( (pParams->PSA_PeakDecayRate > LVPSA_SPEED_HIGH) || 181 (pParams->PSA_Enable > LVM_PSA_ON)) 182 { 183 return (LVM_OUTOFRANGE); 184 } 185 186 187 /* 188 * Set the flag to indicate there are new parameters to use 189 * 190 * Protect the copy of the new parameters from interrupts to avoid possible problems 191 * with loss control parameters. This problem can occur if this control function is called more 192 * than once before a call to the process function. If the process function interrupts 193 * the copy to NewParams then one frame may have mixed parameters, some old and some new. 194 */ 195 pInstance->ControlPending = LVM_TRUE; 196 197 return(LVM_SUCCESS); 198 } 199 200 201 /****************************************************************************************/ 202 /* */ 203 /* FUNCTION: LVM_GetControlParameters */ 204 /* */ 205 /* DESCRIPTION: */ 206 /* Request the LifeVibes module parameters. The current parameter set is returned */ 207 /* via the parameter pointer. */ 208 /* */ 209 /* PARAMETERS: */ 210 /* hInstance Instance handle */ 211 /* pParams Pointer to an empty parameter structure */ 212 /* */ 213 /* RETURNS: */ 214 /* LVM_SUCCESS Succeeded */ 215 /* LVM_NULLADDRESS when any of hInstance or pParams is NULL */ 216 /* */ 217 /* NOTES: */ 218 /* 1. This function may be interrupted by the LVM_Process function */ 219 /* */ 220 /****************************************************************************************/ 221 222 LVM_ReturnStatus_en LVM_GetControlParameters(LVM_Handle_t hInstance, 223 LVM_ControlParams_t *pParams) 224 { 225 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 226 227 228 /* 229 * Check pointer 230 */ 231 if ((pParams == LVM_NULL) || (hInstance == LVM_NULL)) 232 { 233 return (LVM_NULLADDRESS); 234 } 235 *pParams = pInstance->NewParams; 236 237 /* 238 * Copy the filter definitions for the Equaliser 239 */ 240 { 241 LVM_INT16 i; 242 243 if (pInstance->NewParams.EQNB_NBands != 0) 244 for (i=0; i<pInstance->NewParams.EQNB_NBands; i++) 245 { 246 pInstance->pEQNB_UserDefs[i] = pInstance->pEQNB_BandDefs[i]; 247 } 248 pParams->pEQNB_BandDefinition = pInstance->pEQNB_UserDefs; 249 } 250 251 return(LVM_SUCCESS); 252 } 253 254 255 /****************************************************************************************/ 256 /* */ 257 /* FUNCTION: LVM_SetTrebleBoost */ 258 /* */ 259 /* DESCRIPTION: */ 260 /* Enable the treble boost when the settings are appropriate, i.e. non-zero gain */ 261 /* and the sample rate is high enough for the effect to be heard. */ 262 /* */ 263 /* PARAMETERS: */ 264 /* pInstance Pointer to the instance structure */ 265 /* pParams Pointer to the parameters to use */ 266 /* */ 267 /****************************************************************************************/ 268 void LVM_SetTrebleBoost(LVM_Instance_t *pInstance, 269 LVM_ControlParams_t *pParams) 270 { 271 extern FO_C16_LShx_Coefs_t LVM_TrebleBoostCoefs[]; 272 LVM_INT16 Offset; 273 LVM_INT16 EffectLevel = 0; 274 275 /* 276 * Load the coefficients 277 */ 278 if ((pParams->TE_OperatingMode == LVM_TE_ON) && 279 (pParams->SampleRate >= TrebleBoostMinRate) && 280 (pParams->OperatingMode == LVM_MODE_ON) && 281 (pParams->TE_EffectLevel > 0)) 282 { 283 if((pParams->TE_EffectLevel == LVM_TE_LOW_MIPS) && 284 ((pParams->SpeakerType == LVM_HEADPHONES)|| 285 (pParams->SpeakerType == LVM_EX_HEADPHONES))) 286 { 287 pInstance->TE_Active = LVM_FALSE; 288 } 289 else 290 { 291 EffectLevel = pParams->TE_EffectLevel; 292 pInstance->TE_Active = LVM_TRUE; 293 } 294 295 if(pInstance->TE_Active == LVM_TRUE) 296 { 297 /* 298 * Load the coefficients and enabled the treble boost 299 */ 300 Offset = (LVM_INT16)(EffectLevel - 1 + TrebleBoostSteps * (pParams->SampleRate - TrebleBoostMinRate)); 301 FO_2I_D16F32Css_LShx_TRC_WRA_01_Init(&pInstance->pTE_State->TrebleBoost_State, 302 &pInstance->pTE_Taps->TrebleBoost_Taps, 303 &LVM_TrebleBoostCoefs[Offset]); 304 305 /* 306 * Clear the taps 307 */ 308 LoadConst_16((LVM_INT16)0, /* Value */ 309 (void *)&pInstance->pTE_Taps->TrebleBoost_Taps, /* Destination.\ 310 Cast to void: no dereferencing in function */ 311 (LVM_UINT16)(sizeof(pInstance->pTE_Taps->TrebleBoost_Taps)/sizeof(LVM_INT16))); /* Number of words */ 312 } 313 } 314 else 315 { 316 /* 317 * Disable the treble boost 318 */ 319 pInstance->TE_Active = LVM_FALSE; 320 } 321 322 return; 323 } 324 325 326 /************************************************************************************/ 327 /* */ 328 /* FUNCTION: LVM_SetVolume */ 329 /* */ 330 /* DESCRIPTION: */ 331 /* Converts the input volume demand from dBs to linear. */ 332 /* */ 333 /* PARAMETERS: */ 334 /* pInstance Pointer to the instance */ 335 /* pParams Initialisation parameters */ 336 /* */ 337 /************************************************************************************/ 338 void LVM_SetVolume(LVM_Instance_t *pInstance, 339 LVM_ControlParams_t *pParams) 340 { 341 342 LVM_UINT16 dBShifts; /* 6dB shifts */ 343 LVM_UINT16 dBOffset; /* Table offset */ 344 LVM_INT16 Volume = 0; /* Required volume in dBs */ 345 346 /* 347 * Limit the gain to the maximum allowed 348 */ 349 if (pParams->VC_EffectLevel > 0) 350 { 351 Volume = 0; 352 } 353 else 354 { 355 Volume = pParams->VC_EffectLevel; 356 } 357 358 /* Compensate this volume in PSA plot */ 359 if(Volume > -60) /* Limit volume loss to PSA Limits*/ 360 pInstance->PSA_GainOffset=(LVM_INT16)(-Volume);/* Loss is compensated by Gain*/ 361 else 362 pInstance->PSA_GainOffset=(LVM_INT16)60;/* Loss is compensated by Gain*/ 363 364 pInstance->VC_AVLFixedVolume = 0; 365 366 /* 367 * Set volume control and AVL volumes according to headroom and volume user setting 368 */ 369 if(pParams->OperatingMode == LVM_MODE_ON) 370 { 371 /* Default Situation with no AVL and no RS */ 372 if(pParams->EQNB_OperatingMode == LVM_EQNB_ON) 373 { 374 if(Volume > -pInstance->Headroom) 375 Volume = (LVM_INT16)-pInstance->Headroom; 376 } 377 } 378 379 /* 380 * Activate volume control if necessary 381 */ 382 pInstance->VC_Active = LVM_TRUE; 383 if (Volume != 0) 384 { 385 pInstance->VC_VolumedB = Volume; 386 } 387 else 388 { 389 pInstance->VC_VolumedB = 0; 390 } 391 392 /* 393 * Calculate the required gain and shifts 394 */ 395 dBOffset = (LVM_UINT16)((-Volume) % 6); /* Get the dBs 0-5 */ 396 dBShifts = (LVM_UINT16)(Volume / -6); /* Get the 6dB shifts */ 397 398 399 /* 400 * Set the parameters 401 */ 402 if(dBShifts == 0) 403 { 404 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], 405 (LVM_INT32)LVM_VolumeTable[dBOffset]); 406 } 407 else 408 { 409 LVC_Mixer_SetTarget(&pInstance->VC_Volume.MixerStream[0], 410 (((LVM_INT32)LVM_VolumeTable[dBOffset])>>dBShifts)); 411 } 412 pInstance->VC_Volume.MixerStream[0].CallbackSet = 1; 413 if(pInstance->NoSmoothVolume == LVM_TRUE) 414 { 415 LVC_Mixer_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],0,pInstance->Params.SampleRate,2); 416 } 417 else 418 { 419 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_Volume.MixerStream[0],LVM_VC_MIXER_TIME,pInstance->Params.SampleRate,2); 420 } 421 } 422 423 424 /************************************************************************************/ 425 /* */ 426 /* FUNCTION: LVM_SetHeadroom */ 427 /* */ 428 /* DESCRIPTION: */ 429 /* Find suitable headroom based on EQ settings. */ 430 /* */ 431 /* PARAMETERS: */ 432 /* pInstance Pointer to the instance */ 433 /* pParams Initialisation parameters */ 434 /* */ 435 /* RETURNS: */ 436 /* void Nothing */ 437 /* */ 438 /* NOTES: */ 439 /* */ 440 /************************************************************************************/ 441 void LVM_SetHeadroom(LVM_Instance_t *pInstance, 442 LVM_ControlParams_t *pParams) 443 { 444 LVM_INT16 ii, jj; 445 LVM_INT16 Headroom = 0; 446 LVM_INT16 MaxGain = 0; 447 448 449 if ((pParams->EQNB_OperatingMode == LVEQNB_ON) && (pInstance->HeadroomParams.Headroom_OperatingMode == LVM_HEADROOM_ON)) 450 { 451 /* Find typical headroom value */ 452 for(jj = 0; jj < pInstance->HeadroomParams.NHeadroomBands; jj++) 453 { 454 MaxGain = 0; 455 for( ii = 0; ii < pParams->EQNB_NBands; ii++) 456 { 457 if((pParams->pEQNB_BandDefinition[ii].Frequency >= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_Low) && 458 (pParams->pEQNB_BandDefinition[ii].Frequency <= pInstance->HeadroomParams.pHeadroomDefinition[jj].Limit_High)) 459 { 460 if(pParams->pEQNB_BandDefinition[ii].Gain > MaxGain) 461 { 462 MaxGain = pParams->pEQNB_BandDefinition[ii].Gain; 463 } 464 } 465 } 466 467 if((MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset) > Headroom){ 468 Headroom = (LVM_INT16)(MaxGain - pInstance->HeadroomParams.pHeadroomDefinition[jj].Headroom_Offset); 469 } 470 } 471 472 /* Saturate */ 473 if(Headroom < 0) 474 Headroom = 0; 475 } 476 pInstance->Headroom = (LVM_UINT16)Headroom ; 477 478 } 479 480 481 /****************************************************************************************/ 482 /* */ 483 /* FUNCTION: LVM_ApplyNewSettings */ 484 /* */ 485 /* DESCRIPTION: */ 486 /* Applies changes to parametres. This function makes no assumptions about what */ 487 /* each module needs for initialisation and hence passes all parameters to all the */ 488 /* the modules in turn. */ 489 /* */ 490 /* */ 491 /* PARAMETERS: */ 492 /* hInstance Instance handle */ 493 /* */ 494 /* RETURNS: */ 495 /* LVM_Success Succeeded */ 496 /* */ 497 /****************************************************************************************/ 498 499 LVM_ReturnStatus_en LVM_ApplyNewSettings(LVM_Handle_t hInstance) 500 { 501 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 502 LVM_ControlParams_t LocalParams; 503 LVM_INT16 Count = 5; 504 505 506 /* 507 * Copy the new parameters but make sure they didn't change while copying 508 */ 509 do 510 { 511 pInstance->ControlPending = LVM_FALSE; 512 LocalParams = pInstance->NewParams; 513 pInstance->HeadroomParams = pInstance->NewHeadroomParams; 514 Count--; 515 } while ((pInstance->ControlPending != LVM_FALSE) && 516 (Count > 0)); 517 518 /* Clear all internal data if format change*/ 519 if(LocalParams.SourceFormat != pInstance->Params.SourceFormat) 520 { 521 LVM_ClearAudioBuffers(pInstance); 522 pInstance->ControlPending = LVM_FALSE; 523 } 524 525 /* 526 * Update the treble boost if required 527 */ 528 if ((pInstance->Params.SampleRate != LocalParams.SampleRate) || 529 (pInstance->Params.TE_EffectLevel != LocalParams.TE_EffectLevel) || 530 (pInstance->Params.TE_OperatingMode != LocalParams.TE_OperatingMode) || 531 (pInstance->Params.OperatingMode != LocalParams.OperatingMode) || 532 (pInstance->Params.SpeakerType != LocalParams.SpeakerType)) 533 { 534 LVM_SetTrebleBoost(pInstance, 535 &LocalParams); 536 } 537 538 /* 539 * Update the headroom if required 540 */ 541 LVM_SetHeadroom(pInstance, /* Instance pointer */ 542 &LocalParams); /* New parameters */ 543 544 /* 545 * Update the volume if required 546 */ 547 { 548 LVM_SetVolume(pInstance, /* Instance pointer */ 549 &LocalParams); /* New parameters */ 550 } 551 /* Apply balance changes*/ 552 if(pInstance->Params.VC_Balance != LocalParams.VC_Balance) 553 { 554 /* Configure Mixer module for gradual changes to volume*/ 555 if(LocalParams.VC_Balance < 0) 556 { 557 LVM_INT32 Target; 558 /* Drop in right channel volume*/ 559 Target = LVM_MAXINT_16; 560 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 561 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 562 563 Target = dB_to_Lin32((LVM_INT16)(LocalParams.VC_Balance<<4)); 564 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 565 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 566 } 567 else if(LocalParams.VC_Balance >0) 568 { 569 LVM_INT32 Target; 570 /* Drop in left channel volume*/ 571 Target = dB_to_Lin32((LVM_INT16)((-LocalParams.VC_Balance)<<4)); 572 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 573 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 574 575 Target = LVM_MAXINT_16; 576 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 577 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 578 } 579 else 580 { 581 LVM_INT32 Target; 582 /* No drop*/ 583 Target = LVM_MAXINT_16; 584 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[0],Target); 585 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[0],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 586 587 LVC_Mixer_SetTarget(&pInstance->VC_BalanceMix.MixerStream[1],Target); 588 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->VC_BalanceMix.MixerStream[1],LVM_VC_MIXER_TIME,LocalParams.SampleRate,1); 589 } 590 } 591 /* 592 * Update the bass enhancement 593 */ 594 { 595 LVDBE_ReturnStatus_en DBE_Status; 596 LVDBE_Params_t DBE_Params; 597 LVDBE_Handle_t *hDBEInstance = pInstance->hDBEInstance; 598 599 600 /* 601 * Set the new parameters 602 */ 603 if(LocalParams.OperatingMode == LVM_MODE_OFF) 604 { 605 DBE_Params.OperatingMode = LVDBE_OFF; 606 } 607 else 608 { 609 DBE_Params.OperatingMode = (LVDBE_Mode_en)LocalParams.BE_OperatingMode; 610 } 611 DBE_Params.SampleRate = (LVDBE_Fs_en)LocalParams.SampleRate; 612 DBE_Params.EffectLevel = LocalParams.BE_EffectLevel; 613 DBE_Params.CentreFrequency = (LVDBE_CentreFreq_en)LocalParams.BE_CentreFreq; 614 DBE_Params.HPFSelect = (LVDBE_FilterSelect_en)LocalParams.BE_HPF; 615 DBE_Params.HeadroomdB = 0; 616 DBE_Params.VolumeControl = LVDBE_VOLUME_OFF; 617 DBE_Params.VolumedB = 0; 618 619 /* 620 * Make the changes 621 */ 622 DBE_Status = LVDBE_Control(hDBEInstance, 623 &DBE_Params); 624 625 626 /* 627 * Quit if the changes were not accepted 628 */ 629 if (DBE_Status != LVDBE_SUCCESS) 630 { 631 return((LVM_ReturnStatus_en)DBE_Status); 632 } 633 634 635 /* 636 * Set the control flag 637 */ 638 pInstance->DBE_Active = LVM_TRUE; 639 } 640 641 /* 642 * Update the N-Band Equaliser 643 */ 644 { 645 LVEQNB_ReturnStatus_en EQNB_Status; 646 LVEQNB_Params_t EQNB_Params; 647 LVEQNB_Handle_t *hEQNBInstance = pInstance->hEQNBInstance; 648 649 650 /* 651 * Set the new parameters 652 */ 653 654 if(LocalParams.OperatingMode == LVM_MODE_OFF) 655 { 656 EQNB_Params.OperatingMode = LVEQNB_BYPASS; 657 } 658 else 659 { 660 EQNB_Params.OperatingMode = (LVEQNB_Mode_en)LocalParams.EQNB_OperatingMode; 661 } 662 663 EQNB_Params.SampleRate = (LVEQNB_Fs_en)LocalParams.SampleRate; 664 EQNB_Params.NBands = LocalParams.EQNB_NBands; 665 EQNB_Params.pBandDefinition = (LVEQNB_BandDef_t *)LocalParams.pEQNB_BandDefinition; 666 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */ 667 { 668 EQNB_Params.SourceFormat = LVEQNB_STEREO; 669 } 670 else 671 { 672 EQNB_Params.SourceFormat = LVEQNB_MONOINSTEREO; /* Force to Mono-in-Stereo mode */ 673 } 674 675 676 /* 677 * Set the control flag 678 */ 679 if ((LocalParams.OperatingMode == LVM_MODE_ON) && 680 (LocalParams.EQNB_OperatingMode == LVM_EQNB_ON)) 681 { 682 pInstance->EQNB_Active = LVM_TRUE; 683 } 684 else 685 { 686 EQNB_Params.OperatingMode = LVEQNB_BYPASS; 687 } 688 689 /* 690 * Make the changes 691 */ 692 EQNB_Status = LVEQNB_Control(hEQNBInstance, 693 &EQNB_Params); 694 695 696 /* 697 * Quit if the changes were not accepted 698 */ 699 if (EQNB_Status != LVEQNB_SUCCESS) 700 { 701 return((LVM_ReturnStatus_en)EQNB_Status); 702 } 703 704 } 705 706 707 /* 708 * Update concert sound 709 */ 710 { 711 LVCS_ReturnStatus_en CS_Status; 712 LVCS_Params_t CS_Params; 713 LVCS_Handle_t *hCSInstance = pInstance->hCSInstance; 714 LVM_Mode_en CompressorMode=LVM_MODE_ON; 715 716 /* 717 * Set the new parameters 718 */ 719 if(LocalParams.VirtualizerOperatingMode == LVM_MODE_ON) 720 { 721 CS_Params.OperatingMode = LVCS_ON; 722 } 723 else 724 { 725 CS_Params.OperatingMode = LVCS_OFF; 726 } 727 728 if((LocalParams.TE_OperatingMode == LVM_TE_ON) && (LocalParams.TE_EffectLevel == LVM_TE_LOW_MIPS)) 729 { 730 CS_Params.SpeakerType = LVCS_EX_HEADPHONES; 731 } 732 else 733 { 734 CS_Params.SpeakerType = LVCS_HEADPHONES; 735 } 736 737 if (LocalParams.SourceFormat == LVM_STEREO) /* Mono format not supported */ 738 { 739 CS_Params.SourceFormat = LVCS_STEREO; 740 } 741 else 742 { 743 CS_Params.SourceFormat = LVCS_MONOINSTEREO; /* Force to Mono-in-Stereo mode */ 744 } 745 CS_Params.SampleRate = LocalParams.SampleRate; 746 CS_Params.ReverbLevel = LocalParams.VirtualizerReverbLevel; 747 CS_Params.EffectLevel = LocalParams.CS_EffectLevel; 748 749 750 /* 751 * Set the control flag 752 */ 753 if ((LocalParams.OperatingMode == LVM_MODE_ON) && 754 (LocalParams.VirtualizerOperatingMode != LVCS_OFF)) 755 { 756 pInstance->CS_Active = LVM_TRUE; 757 } 758 else 759 { 760 CS_Params.OperatingMode = LVCS_OFF; 761 } 762 763 CS_Params.CompressorMode=CompressorMode; 764 765 /* 766 * Make the changes 767 */ 768 CS_Status = LVCS_Control(hCSInstance, 769 &CS_Params); 770 771 772 /* 773 * Quit if the changes were not accepted 774 */ 775 if (CS_Status != LVCS_SUCCESS) 776 { 777 return((LVM_ReturnStatus_en)CS_Status); 778 } 779 780 } 781 782 /* 783 * Update the Power Spectrum Analyser 784 */ 785 { 786 LVPSA_RETURN PSA_Status; 787 LVPSA_ControlParams_t PSA_Params; 788 pLVPSA_Handle_t *hPSAInstance = pInstance->hPSAInstance; 789 790 791 /* 792 * Set the new parameters 793 */ 794 PSA_Params.Fs = LocalParams.SampleRate; 795 PSA_Params.LevelDetectionSpeed = (LVPSA_LevelDetectSpeed_en)LocalParams.PSA_PeakDecayRate; 796 797 /* 798 * Make the changes 799 */ 800 if(pInstance->InstParams.PSA_Included==LVM_PSA_ON) 801 { 802 PSA_Status = LVPSA_Control(hPSAInstance, 803 &PSA_Params); 804 805 if (PSA_Status != LVPSA_OK) 806 { 807 return((LVM_ReturnStatus_en)PSA_Status); 808 } 809 810 /* 811 * Apply new settings 812 */ 813 PSA_Status = LVPSA_ApplyNewSettings ((LVPSA_InstancePr_t*)hPSAInstance); 814 if(PSA_Status != LVPSA_OK) 815 { 816 return((LVM_ReturnStatus_en)PSA_Status); 817 } 818 } 819 } 820 821 /* 822 * Update the parameters and clear the flag 823 */ 824 pInstance->NoSmoothVolume = LVM_FALSE; 825 pInstance->Params = LocalParams; 826 827 828 return(LVM_SUCCESS); 829 } 830 831 832 /****************************************************************************************/ 833 /* */ 834 /* FUNCTION: LVM_SetHeadroomParams */ 835 /* */ 836 /* DESCRIPTION: */ 837 /* This function is used to set the automatiuc headroom management parameters. */ 838 /* */ 839 /* PARAMETERS: */ 840 /* hInstance Instance Handle */ 841 /* pHeadroomParams Pointer to headroom parameter structure */ 842 /* */ 843 /* RETURNS: */ 844 /* LVM_Success Succeeded */ 845 /* */ 846 /* NOTES: */ 847 /* 1. This function may be interrupted by the LVM_Process function */ 848 /* */ 849 /****************************************************************************************/ 850 851 LVM_ReturnStatus_en LVM_SetHeadroomParams(LVM_Handle_t hInstance, 852 LVM_HeadroomParams_t *pHeadroomParams) 853 { 854 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 855 LVM_UINT16 ii, NBands; 856 857 /* Check for NULL pointers */ 858 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL)) 859 { 860 return (LVM_NULLADDRESS); 861 } 862 if ((pHeadroomParams->NHeadroomBands != 0) && (pHeadroomParams->pHeadroomDefinition == LVM_NULL)) 863 { 864 return (LVM_NULLADDRESS); 865 } 866 867 /* Consider only the LVM_HEADROOM_MAX_NBANDS first bands*/ 868 if (pHeadroomParams->NHeadroomBands > LVM_HEADROOM_MAX_NBANDS) 869 { 870 NBands = LVM_HEADROOM_MAX_NBANDS; 871 } 872 else 873 { 874 NBands = pHeadroomParams->NHeadroomBands; 875 } 876 pInstance->NewHeadroomParams.NHeadroomBands = NBands; 877 878 /* Copy settings in memory */ 879 for(ii = 0; ii < NBands; ii++) 880 { 881 pInstance->pHeadroom_BandDefs[ii] = pHeadroomParams->pHeadroomDefinition[ii]; 882 } 883 884 pInstance->NewHeadroomParams.pHeadroomDefinition = pInstance->pHeadroom_BandDefs; 885 pInstance->NewHeadroomParams.Headroom_OperatingMode = pHeadroomParams->Headroom_OperatingMode; 886 pInstance->ControlPending = LVM_TRUE; 887 888 return(LVM_SUCCESS); 889 } 890 891 /****************************************************************************************/ 892 /* */ 893 /* FUNCTION: LVM_GetHeadroomParams */ 894 /* */ 895 /* DESCRIPTION: */ 896 /* This function is used to get the automatic headroom management parameters. */ 897 /* */ 898 /* PARAMETERS: */ 899 /* hInstance Instance Handle */ 900 /* pHeadroomParams Pointer to headroom parameter structure (output) */ 901 /* */ 902 /* RETURNS: */ 903 /* LVM_SUCCESS Succeeded */ 904 /* LVM_NULLADDRESS When hInstance or pHeadroomParams are NULL */ 905 /* */ 906 /* NOTES: */ 907 /* 1. This function may be interrupted by the LVM_Process function */ 908 /* */ 909 /****************************************************************************************/ 910 911 LVM_ReturnStatus_en LVM_GetHeadroomParams(LVM_Handle_t hInstance, 912 LVM_HeadroomParams_t *pHeadroomParams) 913 { 914 LVM_Instance_t *pInstance =(LVM_Instance_t *)hInstance; 915 LVM_UINT16 ii; 916 917 /* Check for NULL pointers */ 918 if ((hInstance == LVM_NULL) || (pHeadroomParams == LVM_NULL)) 919 { 920 return (LVM_NULLADDRESS); 921 } 922 923 pHeadroomParams->NHeadroomBands = pInstance->NewHeadroomParams.NHeadroomBands; 924 925 926 /* Copy settings in memory */ 927 for(ii = 0; ii < pInstance->NewHeadroomParams.NHeadroomBands; ii++) 928 { 929 pInstance->pHeadroom_UserDefs[ii] = pInstance->pHeadroom_BandDefs[ii]; 930 } 931 932 933 pHeadroomParams->pHeadroomDefinition = pInstance->pHeadroom_UserDefs; 934 pHeadroomParams->Headroom_OperatingMode = pInstance->NewHeadroomParams.Headroom_OperatingMode; 935 return(LVM_SUCCESS); 936 } 937 938 /****************************************************************************************/ 939 /* */ 940 /* FUNCTION: LVM_AlgoCallBack */ 941 /* */ 942 /* DESCRIPTION: */ 943 /* This is the callback function of the algorithm. */ 944 /* */ 945 /* PARAMETERS: */ 946 /* pBundleHandle Pointer to the Instance Handle */ 947 /* pData Pointer to the data */ 948 /* callbackId ID of the callback */ 949 /* */ 950 /* NOTES: */ 951 /* 1. This function may be interrupted by the LVM_Process function */ 952 /* */ 953 /****************************************************************************************/ 954 LVM_INT32 LVM_AlgoCallBack( void *pBundleHandle, 955 void *pData, 956 LVM_INT16 callbackId) 957 { 958 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle; 959 960 (void) pData; 961 962 switch(callbackId & 0xFF00){ 963 case ALGORITHM_CS_ID: 964 switch(callbackId & 0x00FF) 965 { 966 case LVCS_EVENT_ALGOFF: 967 pInstance->CS_Active = LVM_FALSE; 968 break; 969 default: 970 break; 971 } 972 break; 973 case ALGORITHM_EQNB_ID: 974 switch(callbackId & 0x00FF) 975 { 976 case LVEQNB_EVENT_ALGOFF: 977 pInstance->EQNB_Active = LVM_FALSE; 978 break; 979 default: 980 break; 981 } 982 break; 983 default: 984 break; 985 } 986 987 return 0; 988 } 989 990 /****************************************************************************************/ 991 /* */ 992 /* FUNCTION: LVM_VCCallBack */ 993 /* */ 994 /* DESCRIPTION: */ 995 /* This is the callback function of the Volume control. */ 996 /* */ 997 /* PARAMETERS: */ 998 /* pBundleHandle Pointer to the Instance Handle */ 999 /* pGeneralPurpose Pointer to the data */ 1000 /* CallBackParam ID of the callback */ 1001 /* */ 1002 /* NOTES: */ 1003 /* 1. This function may be interrupted by the LVM_Process function */ 1004 /* */ 1005 /****************************************************************************************/ 1006 LVM_INT32 LVM_VCCallBack(void* pBundleHandle, 1007 void* pGeneralPurpose, 1008 short CallBackParam) 1009 { 1010 LVM_Instance_t *pInstance =(LVM_Instance_t *)pBundleHandle; 1011 LVM_INT32 Target; 1012 1013 (void) pGeneralPurpose; 1014 (void) CallBackParam; 1015 1016 /* When volume mixer has reached 0 dB target then stop it to avoid 1017 unnecessary processing. */ 1018 Target = LVC_Mixer_GetTarget(&pInstance->VC_Volume.MixerStream[0]); 1019 1020 if(Target == 0x7FFF) 1021 { 1022 pInstance->VC_Active = LVM_FALSE; 1023 } 1024 return 1; 1025 } 1026